Use JUnit 5 for tests, bump dependencies
This commit is contained in:
parent
681ea148db
commit
c425298b67
20
build.gradle
20
build.gradle
@ -8,8 +8,8 @@ buildscript {
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id 'com.github.ben-manes.versions' version '0.15.0'
|
||||
id "io.spring.dependency-management" version "1.0.3.RELEASE"
|
||||
id 'com.github.ben-manes.versions' version '0.17.0'
|
||||
id "io.spring.dependency-management" version "1.0.4.RELEASE"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
@ -139,19 +139,21 @@ subprojects {
|
||||
}
|
||||
|
||||
dependency 'ch.dissem.msgpack:msgpack:2.0.1'
|
||||
dependency 'org.bouncycastle:bcprov-jdk15on:1.57'
|
||||
dependency 'com.madgag.spongycastle:prov:1.56.0.0'
|
||||
dependency 'org.apache.commons:commons-text:1.1'
|
||||
dependency 'org.flywaydb:flyway-core:4.2.0'
|
||||
dependency 'com.beust:klaxon:0.31'
|
||||
dependency 'org.bouncycastle:bcprov-jdk15on:1.59'
|
||||
dependency 'com.madgag.spongycastle:prov:1.58.0.0'
|
||||
dependency 'org.apache.commons:commons-text:1.2'
|
||||
dependency 'org.flywaydb:flyway-core:5.0.7'
|
||||
dependency 'com.beust:klaxon:2.1.7'
|
||||
|
||||
dependency 'args4j:args4j:2.33'
|
||||
dependency 'org.ini4j:ini4j:0.5.4'
|
||||
dependency 'com.h2database:h2:1.4.196'
|
||||
|
||||
dependency 'junit:junit:4.12'
|
||||
dependency 'org.hamcrest:hamcrest-library:1.3'
|
||||
dependency 'org.hamcrest:java-hamcrest:2.0.0.0'
|
||||
dependency 'com.nhaarman:mockito-kotlin:1.5.0'
|
||||
|
||||
dependency 'org.junit.jupiter:junit-jupiter-api:5.1.0'
|
||||
dependency 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ artifacts {
|
||||
dependencies {
|
||||
compile 'org.slf4j:slf4j-api'
|
||||
compile 'ch.dissem.msgpack:msgpack'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'org.hamcrest:hamcrest-library'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(':cryptography-bc')
|
||||
}
|
||||
|
||||
|
@ -35,11 +35,9 @@ import ch.dissem.bitmessage.utils.TTL
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import ch.dissem.bitmessage.utils.UnixTime.MINUTE
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import org.hamcrest.CoreMatchers.`is`
|
||||
import org.hamcrest.CoreMatchers.notNullValue
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.*
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@ -55,7 +53,8 @@ class BitmessageContextTest {
|
||||
internal var removed = 0
|
||||
|
||||
override fun getItem(initialHash: ByteArray): ProofOfWorkRepository.Item {
|
||||
return items[InventoryVector(initialHash)] ?: throw IllegalArgumentException("${hex(initialHash)} not found in $items")
|
||||
return items[InventoryVector(initialHash)]
|
||||
?: throw IllegalArgumentException("${hex(initialHash)} not found in $items")
|
||||
}
|
||||
|
||||
override fun getItems(): List<ByteArray> {
|
||||
@ -72,7 +71,10 @@ class BitmessageContextTest {
|
||||
}
|
||||
|
||||
override fun putObject(objectMessage: ObjectMessage, nonceTrialsPerByte: Long, extraBytes: Long) {
|
||||
items.put(InventoryVector(cryptography().getInitialHash(objectMessage)), ProofOfWorkRepository.Item(objectMessage, nonceTrialsPerByte, extraBytes))
|
||||
items.put(
|
||||
InventoryVector(cryptography().getInitialHash(objectMessage)),
|
||||
ProofOfWorkRepository.Item(objectMessage, nonceTrialsPerByte, extraBytes)
|
||||
)
|
||||
added++
|
||||
}
|
||||
|
||||
@ -113,7 +115,7 @@ class BitmessageContextTest {
|
||||
TTL.msg = 2 * MINUTE
|
||||
}
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
testPowRepo.reset()
|
||||
}
|
||||
@ -202,61 +204,74 @@ class BitmessageContextTest {
|
||||
ctx.addSubscribtion(address)
|
||||
|
||||
verify(ctx.addresses, atLeastOnce()).save(address)
|
||||
assertThat(address.isSubscribed, `is`(true))
|
||||
assertTrue(address.isSubscribed)
|
||||
verify(ctx.internals.inventory).getObjects(eq(address.stream), any(), any())
|
||||
verify(testListener).receive(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure identity is created`() {
|
||||
assertThat(ctx.createIdentity(false), notNullValue())
|
||||
assertNotNull(ctx.createIdentity(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure message is sent`() {
|
||||
ctx.send(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"), TestUtils.loadContact(),
|
||||
"Subject", "Message")
|
||||
ctx.send(
|
||||
TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"), TestUtils.loadContact(),
|
||||
"Subject", "Message"
|
||||
)
|
||||
verify(ctx.internals.proofOfWorkRepository, timeout(10000)).putObject(
|
||||
argThat { payload.type == ObjectType.MSG }, eq(1000L), eq(1000L))
|
||||
argThat { payload.type == ObjectType.MSG }, eq(1000L), eq(1000L)
|
||||
)
|
||||
assertEquals(2, testPowRepo.added)
|
||||
verify(ctx.messages, timeout(10000).atLeastOnce()).save(argThat<Plaintext> { type == Type.MSG })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure pubkey is requested if it is missing`() {
|
||||
ctx.send(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"),
|
||||
ctx.send(
|
||||
TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"),
|
||||
BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||
"Subject", "Message")
|
||||
"Subject", "Message"
|
||||
)
|
||||
verify(testPowRepo, timeout(10000).atLeastOnce())
|
||||
.putObject(argThat { payload.type == ObjectType.GET_PUBKEY }, eq(1000L), eq(1000L))
|
||||
verify(ctx.messages, timeout(10000).atLeastOnce()).save(argThat<Plaintext> { type == Type.MSG })
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
@Test
|
||||
fun `ensure sender must be identity`() {
|
||||
ctx.send(BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
ctx.send(
|
||||
BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||
"Subject", "Message")
|
||||
BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||
"Subject", "Message"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure broadcast is sent`() {
|
||||
ctx.broadcast(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"),
|
||||
"Subject", "Message")
|
||||
ctx.broadcast(
|
||||
TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"),
|
||||
"Subject", "Message"
|
||||
)
|
||||
verify(ctx.internals.proofOfWorkRepository, timeout(1000).atLeastOnce())
|
||||
.putObject(argThat { payload.type == ObjectType.BROADCAST }, eq(1000L), eq(1000L))
|
||||
verify(testPowEngine).calculateNonce(any(), any(), any<ProofOfWorkEngine.Callback>())
|
||||
verify(ctx.messages, timeout(10000).atLeastOnce()).save(argThat<Plaintext> { type == Type.BROADCAST })
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
@Test
|
||||
fun `ensure sender without private key throws exception`() {
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
val msg = Plaintext.Builder(Type.BROADCAST)
|
||||
.from(BitmessageAddress("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"))
|
||||
.message("Subject", "Message")
|
||||
.build()
|
||||
ctx.send(msg)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure chan is joined`() {
|
||||
@ -326,6 +341,6 @@ class BitmessageContextTest {
|
||||
@Test
|
||||
fun `ensure status contains user agent`() {
|
||||
val userAgent = ctx.status().getProperty("user agent")?.value.toString()
|
||||
assertThat(userAgent, `is`("/Jabit:${BitmessageContext.version}/"))
|
||||
assertEquals("/Jabit:${BitmessageContext.version}/", userAgent)
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ import ch.dissem.bitmessage.entity.payload.V4Broadcast
|
||||
import ch.dissem.bitmessage.entity.payload.V5Broadcast
|
||||
import ch.dissem.bitmessage.utils.TestBase
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class DecryptionTest : TestBase() {
|
||||
@Test
|
||||
|
@ -34,8 +34,8 @@ import ch.dissem.bitmessage.utils.TestUtils
|
||||
import ch.dissem.bitmessage.utils.UnixTime.MINUTE
|
||||
import ch.dissem.bitmessage.utils.UnixTime.now
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
@ -47,7 +47,7 @@ class DefaultMessageListenerTest : TestBase() {
|
||||
cryptography = BouncyCryptography()
|
||||
)
|
||||
|
||||
@Before
|
||||
@BeforeAll
|
||||
fun setUp() {
|
||||
listener = ctx.networkListener as DefaultMessageListener
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import ch.dissem.bitmessage.utils.TestBase
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class EncryptionTest : TestBase() {
|
||||
@Test
|
||||
|
@ -28,10 +28,9 @@ import ch.dissem.bitmessage.ports.ProofOfWorkRepository
|
||||
import ch.dissem.bitmessage.utils.Singleton
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.*
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@ -44,7 +43,7 @@ class ProofOfWorkServiceTest {
|
||||
|
||||
private var obj by Delegates.notNull<ObjectMessage>()
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
cryptography = spy(BouncyCryptography())
|
||||
Singleton.initialize(cryptography)
|
||||
@ -96,6 +95,6 @@ class ProofOfWorkServiceTest {
|
||||
verify(ctx.proofOfWorkRepository).removeObject(eq(initialHash))
|
||||
verify(ctx.inventory).storeObject(eq(objectMessage))
|
||||
verify(ctx.networkHandler).offer(eq(objectMessage.inventoryVector))
|
||||
assertThat(plaintext.inventoryVector, equalTo(objectMessage.inventoryVector))
|
||||
assertEquals(objectMessage.inventoryVector, plaintext.inventoryVector)
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import ch.dissem.bitmessage.entity.payload.Pubkey
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.utils.TestBase
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class SignatureTest : TestBase() {
|
||||
@Test
|
||||
|
@ -22,16 +22,15 @@ import ch.dissem.bitmessage.entity.payload.Pubkey.Feature.INCLUDE_DESTINATION
|
||||
import ch.dissem.bitmessage.entity.payload.V4Pubkey
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.utils.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
class BitmessageAddressTest : TestBase() {
|
||||
@Test
|
||||
fun `ensure feature flag is calculated correctly`() {
|
||||
Assert.assertEquals(1, Pubkey.Feature.bitfield(DOES_ACK))
|
||||
assertEquals(1, Pubkey.Feature.bitfield(DOES_ACK))
|
||||
assertEquals(2, Pubkey.Feature.bitfield(INCLUDE_DESTINATION))
|
||||
assertEquals(3, Pubkey.Feature.bitfield(DOES_ACK, INCLUDE_DESTINATION))
|
||||
}
|
||||
@ -74,7 +73,7 @@ class BitmessageAddressTest : TestBase() {
|
||||
try {
|
||||
address.pubkey = pubkey
|
||||
} catch (e: Exception) {
|
||||
fail(e.message)
|
||||
fail<Unit>(e.message)
|
||||
}
|
||||
|
||||
}
|
||||
@ -82,7 +81,7 @@ class BitmessageAddressTest : TestBase() {
|
||||
@Test
|
||||
fun `ensure V3Pubkey can be imported`() {
|
||||
val address = BitmessageAddress("BM-2D9Vc5rFxxR5vTi53T9gkLfemViHRMVLQZ")
|
||||
Assert.assertArrayEquals(Bytes.fromHex("007402be6e76c3cb87caa946d0c003a3d4d8e1d5"), address.ripe)
|
||||
assertArrayEquals(Bytes.fromHex("007402be6e76c3cb87caa946d0c003a3d4d8e1d5"), address.ripe)
|
||||
|
||||
val objectMessage = TestUtils.loadObjectMessage(3, "V3Pubkey.payload")
|
||||
val pubkey = objectMessage.payload as Pubkey
|
||||
@ -90,7 +89,7 @@ class BitmessageAddressTest : TestBase() {
|
||||
try {
|
||||
address.pubkey = pubkey
|
||||
} catch (e: Exception) {
|
||||
fail(e.message)
|
||||
fail<Unit>(e.message)
|
||||
}
|
||||
|
||||
assertArrayEquals(Bytes.fromHex("007402be6e76c3cb87caa946d0c003a3d4d8e1d5"), pubkey.ripe)
|
||||
@ -107,7 +106,7 @@ class BitmessageAddressTest : TestBase() {
|
||||
try {
|
||||
address.pubkey = pubkey
|
||||
} catch (e: Exception) {
|
||||
fail(e.message)
|
||||
fail<Unit>(e.message)
|
||||
}
|
||||
|
||||
assertTrue(address.has(DOES_ACK))
|
||||
|
File diff suppressed because one or more lines are too long
@ -24,9 +24,8 @@ import ch.dissem.bitmessage.entity.valueobject.extended.Message
|
||||
import ch.dissem.bitmessage.factory.Factory
|
||||
import ch.dissem.bitmessage.utils.TestBase
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.hamcrest.Matchers.`is`
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.ObjectInputStream
|
||||
@ -95,7 +94,7 @@ class SerializationTest : TestBase() {
|
||||
received.isAccessible = true
|
||||
received.set(actual, null)
|
||||
|
||||
assertThat(expected, `is`(actual))
|
||||
assertEquals(actual, expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -103,10 +102,12 @@ class SerializationTest : TestBase() {
|
||||
val expected = Plaintext.Builder(MSG)
|
||||
.from(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"))
|
||||
.to(TestUtils.loadContact())
|
||||
.message(Message.Builder()
|
||||
.message(
|
||||
Message.Builder()
|
||||
.subject("Subject")
|
||||
.body("Message")
|
||||
.build())
|
||||
.build()
|
||||
)
|
||||
.ackData("ackMessage".toByteArray())
|
||||
.signature(ByteArray(0))
|
||||
.build()
|
||||
@ -127,10 +128,12 @@ class SerializationTest : TestBase() {
|
||||
fun `ensure plaintext without recipient can be serialized (needed for saving drafts)`() {
|
||||
val expected = Plaintext.Builder(MSG)
|
||||
.from(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"))
|
||||
.message(Message.Builder()
|
||||
.message(
|
||||
Message.Builder()
|
||||
.subject("Subject")
|
||||
.body("Message")
|
||||
.build())
|
||||
.build()
|
||||
)
|
||||
.signature(ByteArray(0))
|
||||
.status(Plaintext.Status.DRAFT)
|
||||
.build()
|
||||
|
@ -20,19 +20,25 @@ import ch.dissem.bitmessage.utils.Bytes
|
||||
import ch.dissem.bitmessage.utils.CallbackWaiter
|
||||
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import ch.dissem.bitmessage.utils.TestBase
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertTimeoutPreemptively
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Duration.ofSeconds
|
||||
|
||||
class ProofOfWorkEngineTest : TestBase() {
|
||||
@Test(timeout = 90000)
|
||||
@Test
|
||||
fun `test SimplePOWEngine`() {
|
||||
assertTimeoutPreemptively(ofSeconds(90)) {
|
||||
testPOW(SimplePOWEngine())
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 90000)
|
||||
@Test
|
||||
fun `test MultiThreadedPOWEngine`() {
|
||||
assertTimeoutPreemptively(ofSeconds(90)) {
|
||||
testPOW(MultiThreadedPOWEngine())
|
||||
}
|
||||
}
|
||||
|
||||
private fun testPOW(engine: ProofOfWorkEngine) {
|
||||
val initialHash = cryptography().sha512(byteArrayOf(1, 3, 6, 4))
|
||||
@ -65,6 +71,6 @@ class ProofOfWorkEngineTest : TestBase() {
|
||||
val nonce2 = waiter2.waitForValue()!!
|
||||
println("Calculating nonce1 took ${waiter2.time}ms")
|
||||
assertTrue(Bytes.lt(cryptography().doubleSha512(nonce2, initialHash2), target2, 8))
|
||||
assertTrue("Second nonce1 must be quicker to find", waiter1.time > waiter2.time)
|
||||
assertTrue(waiter1.time > waiter2.time, "Second nonce1 must be quicker to find")
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,8 @@
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||
import org.hamcrest.Matchers.`is`
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class Base64Test {
|
||||
@Test
|
||||
@ -29,7 +28,7 @@ class Base64Test {
|
||||
val data = cryptography.randomBytes(i)
|
||||
val string = Base64.encodeToString(data)
|
||||
val decoded = Base64.decode(string)
|
||||
assertThat(decoded, `is`(data))
|
||||
assertEquals(data, decoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,10 @@
|
||||
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertArrayEquals
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
|
||||
@ -46,7 +46,11 @@ class BytesTest {
|
||||
for (i in 1..255) {
|
||||
val bytes = byteArrayOf(0, v.toByte())
|
||||
Bytes.inc(bytes, i.toByte())
|
||||
assertArrayEquals("value = " + v + "; inc = " + i + "; expected = " + (v + i), TestUtils.int16(v + i), bytes)
|
||||
assertArrayEquals(
|
||||
TestUtils.int16(v + i),
|
||||
bytes,
|
||||
"value = " + v + "; inc = " + i + "; expected = " + (v + i)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,7 +59,7 @@ class BytesTest {
|
||||
* This test is used to compare different implementations of the single byte lt comparison. It an safely be ignored.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
@Disabled
|
||||
fun `test lower than single byte`() {
|
||||
val a = ByteArray(1)
|
||||
val b = ByteArray(1)
|
||||
@ -85,10 +89,13 @@ class BytesTest {
|
||||
val a = BigInteger.valueOf(rnd.nextLong()).pow(rnd.nextInt(5) + 1).abs()
|
||||
val b = BigInteger.valueOf(rnd.nextLong()).pow(rnd.nextInt(5) + 1).abs()
|
||||
println("a = " + a.toString(16) + "\tb = " + b.toString(16))
|
||||
assertEquals(a.compareTo(b) == -1, Bytes.lt(
|
||||
assertEquals(
|
||||
a.compareTo(b) == -1, Bytes.lt(
|
||||
Bytes.expand(a.toByteArray(), 100),
|
||||
Bytes.expand(b.toByteArray(), 100),
|
||||
100))
|
||||
100
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,17 +16,12 @@
|
||||
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import java.util.LinkedList
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class CollectionsTest {
|
||||
@Test
|
||||
fun `ensure select random returns maximum possible items`() {
|
||||
val list = LinkedList<Int>()
|
||||
list += 0..9
|
||||
assertEquals(9, Collections.selectRandom(9, list).size)
|
||||
assertEquals(9, Collections.selectRandom(9, listOf(0..9)).size)
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,8 @@ import ch.dissem.bitmessage.entity.valueobject.extended.Message
|
||||
import ch.dissem.bitmessage.ports.MessageRepository
|
||||
import ch.dissem.bitmessage.utils.TestUtils.RANDOM
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import org.hamcrest.Matchers.`is`
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.*
|
||||
|
||||
class ConversationServiceTest : TestBase() {
|
||||
@ -45,7 +44,7 @@ class ConversationServiceTest : TestBase() {
|
||||
|
||||
doReturn(expected).whenever(conversationService).getConversation(any<UUID>())
|
||||
val actual = conversationService.getConversation(UUID.randomUUID())
|
||||
assertThat(actual, `is`(expected))
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -53,57 +52,69 @@ class ConversationServiceTest : TestBase() {
|
||||
fun conversation(alice: BitmessageAddress, bob: BitmessageAddress): List<Plaintext> {
|
||||
val result = LinkedList<Plaintext>()
|
||||
|
||||
val older = plaintext(alice, bob,
|
||||
val older = plaintext(
|
||||
alice, bob,
|
||||
Message.Builder()
|
||||
.subject("hey there")
|
||||
.body("does it work?")
|
||||
.build(),
|
||||
Plaintext.Status.SENT)
|
||||
Plaintext.Status.SENT
|
||||
)
|
||||
result.add(older)
|
||||
|
||||
val root = plaintext(alice, bob,
|
||||
val root = plaintext(
|
||||
alice, bob,
|
||||
Message.Builder()
|
||||
.subject("new test")
|
||||
.body("There's a new test in town!")
|
||||
.build(),
|
||||
Plaintext.Status.SENT)
|
||||
Plaintext.Status.SENT
|
||||
)
|
||||
result.add(root)
|
||||
|
||||
result.add(
|
||||
plaintext(bob, alice,
|
||||
plaintext(
|
||||
bob, alice,
|
||||
Message.Builder()
|
||||
.subject("Re: new test (1a)")
|
||||
.body("Nice!")
|
||||
.addParent(root)
|
||||
.build(),
|
||||
Plaintext.Status.RECEIVED)
|
||||
Plaintext.Status.RECEIVED
|
||||
)
|
||||
)
|
||||
|
||||
val latest = plaintext(bob, alice,
|
||||
val latest = plaintext(
|
||||
bob, alice,
|
||||
Message.Builder()
|
||||
.subject("Re: new test (2b)")
|
||||
.body("PS: it did work!")
|
||||
.addParent(root)
|
||||
.addParent(older)
|
||||
.build(),
|
||||
Plaintext.Status.RECEIVED)
|
||||
Plaintext.Status.RECEIVED
|
||||
)
|
||||
result.add(latest)
|
||||
|
||||
result.add(
|
||||
plaintext(alice, bob,
|
||||
plaintext(
|
||||
alice, bob,
|
||||
Message.Builder()
|
||||
.subject("Re: new test (2)")
|
||||
.body("")
|
||||
.addParent(latest)
|
||||
.build(),
|
||||
Plaintext.Status.DRAFT)
|
||||
Plaintext.Status.DRAFT
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun plaintext(from: BitmessageAddress, to: BitmessageAddress,
|
||||
content: ExtendedEncoding, status: Plaintext.Status): Plaintext {
|
||||
fun plaintext(
|
||||
from: BitmessageAddress, to: BitmessageAddress,
|
||||
content: ExtendedEncoding, status: Plaintext.Status
|
||||
): Plaintext {
|
||||
val builder = Plaintext.Builder(MSG)
|
||||
.IV(TestUtils.randomInventoryVector())
|
||||
.from(from)
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assumptions
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
class EncodeTest {
|
||||
@ -111,7 +112,8 @@ class EncodeTest {
|
||||
|
||||
|
||||
fun checkBytes(stream: ByteArrayOutputStream, vararg bytes: Int) {
|
||||
assertEquals(bytes.size, stream.size())
|
||||
Assumptions.assumeTrue(bytes.size == stream.size())
|
||||
|
||||
val streamBytes = stream.toByteArray()
|
||||
|
||||
for (i in bytes.indices) {
|
||||
|
@ -16,14 +16,12 @@
|
||||
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class SqlStringsTest {
|
||||
@Test
|
||||
fun `ensure join works with long array`() {
|
||||
val test = longArrayOf(1L, 2L)
|
||||
assertEquals("1, 2", SqlStrings.join(*test))
|
||||
assertEquals("1, 2", SqlStrings.join(1L, 2L))
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,8 @@
|
||||
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class StringsTest {
|
||||
@Test
|
||||
|
@ -17,15 +17,16 @@
|
||||
package ch.dissem.bitmessage.utils
|
||||
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
open class TestBase {
|
||||
companion object {
|
||||
@BeforeClass
|
||||
@JvmStatic fun setUpClass() {
|
||||
@BeforeAll
|
||||
@JvmStatic
|
||||
fun setUpClass() {
|
||||
Singleton.initialize(BouncyCryptography())
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import ch.dissem.bitmessage.factory.Factory
|
||||
import ch.dissem.bitmessage.ports.*
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import com.nhaarman.mockito_kotlin.spy
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
@ -54,7 +54,8 @@ object TestUtils {
|
||||
fun loadObjectMessage(version: Int, resourceName: String): ObjectMessage {
|
||||
val data = getBytes(resourceName)
|
||||
val input = ByteArrayInputStream(data)
|
||||
return Factory.getObjectMessage(version, input, data.size) ?: throw NoSuchElementException("error loading object message")
|
||||
return Factory.getObjectMessage(version, input, data.size)
|
||||
?: throw NoSuchElementException("error loading object message")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
@ -13,7 +13,8 @@ uploadArchives {
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'org.bouncycastle:bcprov-jdk15on'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||
}
|
||||
|
@ -22,14 +22,15 @@ import ch.dissem.bitmessage.entity.payload.GenericPayload
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.exception.InsufficientProofOfWorkException
|
||||
import ch.dissem.bitmessage.ports.MultiThreadedPOWEngine
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkEngine
|
||||
import ch.dissem.bitmessage.utils.*
|
||||
import ch.dissem.bitmessage.utils.CallbackWaiter
|
||||
import ch.dissem.bitmessage.utils.Singleton
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import ch.dissem.bitmessage.utils.UnixTime
|
||||
import ch.dissem.bitmessage.utils.UnixTime.DAY
|
||||
import ch.dissem.bitmessage.utils.UnixTime.MINUTE
|
||||
import ch.dissem.bitmessage.utils.UnixTime.now
|
||||
import org.hamcrest.CoreMatchers.`is`
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import javax.xml.bind.DatatypeConverter
|
||||
|
||||
@ -63,7 +64,7 @@ class CryptographyTest {
|
||||
assertArrayEquals(crypto.sha512(TEST_SHA512), crypto.doubleSha512(TEST_VALUE))
|
||||
}
|
||||
|
||||
@Test(expected = InsufficientProofOfWorkException::class)
|
||||
@Test
|
||||
fun `ensure exception for insufficient proof of work`() {
|
||||
val objectMessage = ObjectMessage.Builder()
|
||||
.nonce(ByteArray(8))
|
||||
@ -71,8 +72,10 @@ class CryptographyTest {
|
||||
.objectType(0)
|
||||
.payload(GenericPayload.read(0, 1, ByteArrayInputStream(ByteArray(0)), 0))
|
||||
.build()
|
||||
assertThrows(InsufficientProofOfWorkException::class.java) {
|
||||
crypto.checkProofOfWork(objectMessage, 1000, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure proof of work is calculated correctly`() {
|
||||
@ -94,7 +97,7 @@ class CryptographyTest {
|
||||
try {
|
||||
crypto.checkProofOfWork(objectMessage, 1000, 1000)
|
||||
} catch (e: InsufficientProofOfWorkException) {
|
||||
fail(e.message)
|
||||
fail<Unit>(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,13 +111,15 @@ class CryptographyTest {
|
||||
assertArrayEquals(data, decrypted)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
@Test
|
||||
fun `ensure decryption fails with invalid cypher text`() {
|
||||
val data = crypto.randomBytes(128)
|
||||
val key_e = crypto.randomBytes(32)
|
||||
val iv = crypto.randomBytes(16)
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
crypto.crypt(false, data, key_e, iv)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure multiplication works correctly`() {
|
||||
@ -132,7 +137,7 @@ class CryptographyTest {
|
||||
val data = crypto.randomBytes(100)
|
||||
val privateKey = PrivateKey(false, 1, 1000, 1000)
|
||||
val signature = crypto.getSignature(data, privateKey)
|
||||
assertThat(crypto.isSignatureValid(data, signature, privateKey.pubkey), `is`(true))
|
||||
assertTrue(crypto.isSignatureValid(data, signature, privateKey.pubkey))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -141,18 +146,24 @@ class CryptographyTest {
|
||||
val privateKey = PrivateKey(false, 1, 1000, 1000)
|
||||
val signature = crypto.getSignature(data, privateKey)
|
||||
data[0]++
|
||||
assertThat(crypto.isSignatureValid(data, signature, privateKey.pubkey), `is`(false))
|
||||
assertFalse(crypto.isSignatureValid(data, signature, privateKey.pubkey))
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TEST_VALUE = "teststring".toByteArray()
|
||||
val TEST_SHA1 = DatatypeConverter.parseHexBinary(""
|
||||
+ "b8473b86d4c2072ca9b08bd28e373e8253e865c4")
|
||||
val TEST_SHA512 = DatatypeConverter.parseHexBinary(""
|
||||
val TEST_SHA1 = DatatypeConverter.parseHexBinary(
|
||||
""
|
||||
+ "b8473b86d4c2072ca9b08bd28e373e8253e865c4"
|
||||
)
|
||||
val TEST_SHA512 = DatatypeConverter.parseHexBinary(
|
||||
""
|
||||
+ "6253b39071e5df8b5098f59202d414c37a17d6a38a875ef5f8c7d89b0212b028"
|
||||
+ "692d3d2090ce03ae1de66c862fa8a561e57ed9eb7935ce627344f742c0931d72")
|
||||
val TEST_RIPEMD160 = DatatypeConverter.parseHexBinary(""
|
||||
+ "cd566972b5e50104011a92b59fa8e0b1234851ae")
|
||||
+ "692d3d2090ce03ae1de66c862fa8a561e57ed9eb7935ce627344f742c0931d72"
|
||||
)
|
||||
val TEST_RIPEMD160 = DatatypeConverter.parseHexBinary(
|
||||
""
|
||||
+ "cd566972b5e50104011a92b59fa8e0b1234851ae"
|
||||
)
|
||||
|
||||
private val crypto = BouncyCryptography()
|
||||
|
||||
|
@ -13,7 +13,8 @@ uploadArchives {
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'com.madgag.spongycastle:prov'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ dependencies {
|
||||
compile 'args4j:args4j'
|
||||
compile 'com.h2database:h2'
|
||||
compile 'org.apache.commons:commons-text'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
}
|
||||
|
@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* 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 ch.dissem.bitmessage;
|
||||
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.entity.Plaintext;
|
||||
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler;
|
||||
import ch.dissem.bitmessage.ports.DefaultLabeler;
|
||||
import ch.dissem.bitmessage.ports.Labeler;
|
||||
import ch.dissem.bitmessage.repository.*;
|
||||
import ch.dissem.bitmessage.utils.TTL;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK;
|
||||
import static ch.dissem.bitmessage.utils.UnixTime.MINUTE;
|
||||
import static com.nhaarman.mockito_kotlin.MockitoKt.*;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
public class SystemTest {
|
||||
private static int port = 6000;
|
||||
|
||||
private BitmessageContext alice;
|
||||
private BitmessageAddress aliceIdentity;
|
||||
private Labeler aliceLabeler;
|
||||
|
||||
private BitmessageContext bob;
|
||||
private TestListener bobListener;
|
||||
private BitmessageAddress bobIdentity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
TTL.msg(5 * MINUTE);
|
||||
TTL.getpubkey(5 * MINUTE);
|
||||
TTL.pubkey(5 * MINUTE);
|
||||
|
||||
int alicePort = port++;
|
||||
int bobPort = port++;
|
||||
{
|
||||
JdbcConfig aliceDB = new JdbcConfig("jdbc:h2:mem:alice;DB_CLOSE_DELAY=-1", "sa", "");
|
||||
aliceLabeler = spy(new DebugLabeler("Alice"));
|
||||
TestListener aliceListener = new TestListener();
|
||||
alice = new BitmessageContext.Builder()
|
||||
.addressRepo(new JdbcAddressRepository(aliceDB))
|
||||
.inventory(new JdbcInventory(aliceDB))
|
||||
.labelRepo(new JdbcLabelRepository(aliceDB))
|
||||
.messageRepo(new JdbcMessageRepository(aliceDB))
|
||||
.powRepo(new JdbcProofOfWorkRepository(aliceDB))
|
||||
.nodeRegistry(new TestNodeRegistry(bobPort))
|
||||
.networkHandler(new NioNetworkHandler())
|
||||
.cryptography(new BouncyCryptography())
|
||||
.listener(aliceListener)
|
||||
.labeler(aliceLabeler)
|
||||
.build();
|
||||
alice.internals().getPreferences().setPort(alicePort);
|
||||
alice.startup();
|
||||
aliceIdentity = alice.createIdentity(false, DOES_ACK);
|
||||
}
|
||||
{
|
||||
JdbcConfig bobDB = new JdbcConfig("jdbc:h2:mem:bob;DB_CLOSE_DELAY=-1", "sa", "");
|
||||
bobListener = new TestListener();
|
||||
bob = new BitmessageContext.Builder()
|
||||
.addressRepo(new JdbcAddressRepository(bobDB))
|
||||
.inventory(new JdbcInventory(bobDB))
|
||||
.labelRepo(new JdbcLabelRepository(bobDB))
|
||||
.messageRepo(new JdbcMessageRepository(bobDB))
|
||||
.powRepo(new JdbcProofOfWorkRepository(bobDB))
|
||||
.nodeRegistry(new TestNodeRegistry(alicePort))
|
||||
.networkHandler(new NioNetworkHandler())
|
||||
.cryptography(new BouncyCryptography())
|
||||
.listener(bobListener)
|
||||
.labeler(new DebugLabeler("Bob"))
|
||||
.build();
|
||||
bob.internals().getPreferences().setPort(bobPort);
|
||||
bob.startup();
|
||||
bobIdentity = bob.createIdentity(false, DOES_ACK);
|
||||
}
|
||||
((DebugLabeler) alice.labeler()).init(aliceIdentity, bobIdentity);
|
||||
((DebugLabeler) bob.labeler()).init(aliceIdentity, bobIdentity);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
alice.shutdown();
|
||||
bob.shutdown();
|
||||
}
|
||||
|
||||
@Test(timeout = 120_000)
|
||||
public void ensureAliceCanSendMessageToBob() throws Exception {
|
||||
String originalMessage = UUID.randomUUID().toString();
|
||||
alice.send(aliceIdentity, new BitmessageAddress(bobIdentity.getAddress()), "Subject", originalMessage);
|
||||
|
||||
Plaintext plaintext = bobListener.get(2, TimeUnit.MINUTES);
|
||||
|
||||
assertThat(plaintext.getType(), equalTo(Plaintext.Type.MSG));
|
||||
assertThat(plaintext.getText(), equalTo(originalMessage));
|
||||
|
||||
verify(aliceLabeler, timeout(TimeUnit.MINUTES.toMillis(2)).atLeastOnce())
|
||||
.markAsAcknowledged(any());
|
||||
}
|
||||
|
||||
@Test(timeout = 30_000)
|
||||
public void ensureBobCanReceiveBroadcastFromAlice() throws Exception {
|
||||
String originalMessage = UUID.randomUUID().toString();
|
||||
bob.addSubscribtion(new BitmessageAddress(aliceIdentity.getAddress()));
|
||||
alice.broadcast(aliceIdentity, "Subject", originalMessage);
|
||||
|
||||
Plaintext plaintext = bobListener.get(15, TimeUnit.MINUTES);
|
||||
|
||||
assertThat(plaintext.getType(), equalTo(Plaintext.Type.BROADCAST));
|
||||
assertThat(plaintext.getText(), equalTo(originalMessage));
|
||||
}
|
||||
|
||||
private static class DebugLabeler extends DefaultLabeler {
|
||||
private final Logger LOG = LoggerFactory.getLogger("Labeler");
|
||||
final String name;
|
||||
String alice;
|
||||
String bob;
|
||||
|
||||
private DebugLabeler(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private void init(BitmessageAddress alice, BitmessageAddress bob) {
|
||||
this.alice = alice.getAddress();
|
||||
this.bob = bob.getAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabels(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Received");
|
||||
super.setLabels(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsDraft(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Draft");
|
||||
super.markAsDraft(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsSending(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Sending");
|
||||
super.markAsSending(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsSent(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Sent");
|
||||
super.markAsSent(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsAcknowledged(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Acknowledged");
|
||||
super.markAsAcknowledged(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsRead(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Read");
|
||||
super.markAsRead(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsUnread(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Unread");
|
||||
super.markAsUnread(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Cleared");
|
||||
super.delete(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void archive(Plaintext msg) {
|
||||
LOG.info(name + ": From " + name(msg.getFrom()) + ": Archived");
|
||||
super.archive(msg);
|
||||
}
|
||||
|
||||
private String name(BitmessageAddress address) {
|
||||
if (alice.equals(address.getAddress()))
|
||||
return "Alice";
|
||||
else if (bob.equals(address.getAddress()))
|
||||
return "Bob";
|
||||
else
|
||||
return "Unknown (" + address.getAddress() + ")";
|
||||
}
|
||||
}
|
||||
}
|
215
demo/src/test/java/ch/dissem/bitmessage/SystemTest.kt
Normal file
215
demo/src/test/java/ch/dissem/bitmessage/SystemTest.kt
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* 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 ch.dissem.bitmessage
|
||||
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK
|
||||
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler
|
||||
import ch.dissem.bitmessage.ports.DefaultLabeler
|
||||
import ch.dissem.bitmessage.ports.Labeler
|
||||
import ch.dissem.bitmessage.repository.*
|
||||
import ch.dissem.bitmessage.utils.TTL
|
||||
import ch.dissem.bitmessage.utils.UnixTime.MINUTE
|
||||
import com.nhaarman.mockito_kotlin.spy
|
||||
import com.nhaarman.mockito_kotlin.timeout
|
||||
import com.nhaarman.mockito_kotlin.verify
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTimeoutPreemptively
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.time.Duration.ofMinutes
|
||||
import java.time.Duration.ofSeconds
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
class SystemTest {
|
||||
|
||||
private lateinit var alice: BitmessageContext
|
||||
private lateinit var aliceIdentity: BitmessageAddress
|
||||
private lateinit var aliceLabeler: Labeler
|
||||
|
||||
private lateinit var bob: BitmessageContext
|
||||
private lateinit var bobListener: TestListener
|
||||
private lateinit var bobIdentity: BitmessageAddress
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
TTL.msg = 5 * MINUTE
|
||||
TTL.getpubkey = 5 * MINUTE
|
||||
TTL.pubkey = 5 * MINUTE
|
||||
|
||||
val alicePort = port++
|
||||
val bobPort = port++
|
||||
run {
|
||||
val aliceDB = JdbcConfig("jdbc:h2:mem:alice;DB_CLOSE_DELAY=-1", "sa", "")
|
||||
aliceLabeler = spy(DebugLabeler("Alice"))
|
||||
val aliceListener = TestListener()
|
||||
alice = BitmessageContext.Builder()
|
||||
.addressRepo(JdbcAddressRepository(aliceDB))
|
||||
.inventory(JdbcInventory(aliceDB))
|
||||
.labelRepo(JdbcLabelRepository(aliceDB))
|
||||
.messageRepo(JdbcMessageRepository(aliceDB))
|
||||
.powRepo(JdbcProofOfWorkRepository(aliceDB))
|
||||
.nodeRegistry(TestNodeRegistry(bobPort))
|
||||
.networkHandler(NioNetworkHandler())
|
||||
.cryptography(BouncyCryptography())
|
||||
.listener(aliceListener)
|
||||
.labeler(aliceLabeler)
|
||||
.build()
|
||||
alice.internals.preferences.port = alicePort
|
||||
alice.startup()
|
||||
aliceIdentity = alice.createIdentity(false, DOES_ACK)
|
||||
}
|
||||
run {
|
||||
val bobDB = JdbcConfig("jdbc:h2:mem:bob;DB_CLOSE_DELAY=-1", "sa", "")
|
||||
bobListener = TestListener()
|
||||
bob = BitmessageContext.Builder()
|
||||
.addressRepo(JdbcAddressRepository(bobDB))
|
||||
.inventory(JdbcInventory(bobDB))
|
||||
.labelRepo(JdbcLabelRepository(bobDB))
|
||||
.messageRepo(JdbcMessageRepository(bobDB))
|
||||
.powRepo(JdbcProofOfWorkRepository(bobDB))
|
||||
.nodeRegistry(TestNodeRegistry(alicePort))
|
||||
.networkHandler(NioNetworkHandler())
|
||||
.cryptography(BouncyCryptography())
|
||||
.listener(bobListener)
|
||||
.labeler(DebugLabeler("Bob"))
|
||||
.build()
|
||||
bob.internals.preferences.port = bobPort
|
||||
bob.startup()
|
||||
bobIdentity = bob.createIdentity(false, DOES_ACK)
|
||||
}
|
||||
(alice.labeler as DebugLabeler).init(aliceIdentity, bobIdentity)
|
||||
(bob.labeler as DebugLabeler).init(aliceIdentity, bobIdentity)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
alice.shutdown()
|
||||
bob.shutdown()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun ensureAliceCanSendMessageToBob() {
|
||||
assertTimeoutPreemptively(ofMinutes(2)) {
|
||||
val originalMessage = UUID.randomUUID().toString()
|
||||
alice.send(aliceIdentity, BitmessageAddress(bobIdentity.address), "Subject", originalMessage)
|
||||
|
||||
val plaintext = bobListener[2, TimeUnit.MINUTES]
|
||||
|
||||
assertEquals(Plaintext.Type.MSG, plaintext.type)
|
||||
assertEquals(originalMessage, plaintext.text)
|
||||
|
||||
verify(
|
||||
aliceLabeler,
|
||||
timeout(TimeUnit.MINUTES.toMillis(2)).atLeastOnce()
|
||||
).markAsAcknowledged(any<Plaintext>())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun ensureBobCanReceiveBroadcastFromAlice() {
|
||||
assertTimeoutPreemptively(ofSeconds(30)) {
|
||||
val originalMessage = UUID.randomUUID().toString()
|
||||
bob.addSubscribtion(BitmessageAddress(aliceIdentity.address))
|
||||
alice.broadcast(aliceIdentity, "Subject", originalMessage)
|
||||
|
||||
val plaintext = bobListener[15, TimeUnit.MINUTES]
|
||||
|
||||
assertEquals(Plaintext.Type.BROADCAST, plaintext.type)
|
||||
assertEquals(originalMessage, plaintext.text)
|
||||
}
|
||||
}
|
||||
|
||||
internal class DebugLabeler internal constructor(private val name: String) : DefaultLabeler() {
|
||||
private val LOG = LoggerFactory.getLogger("Labeler")
|
||||
private lateinit var alice: String
|
||||
private lateinit var bob: String
|
||||
|
||||
internal fun init(alice: BitmessageAddress, bob: BitmessageAddress) {
|
||||
this.alice = alice.address
|
||||
this.bob = bob.address
|
||||
}
|
||||
|
||||
override fun setLabels(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Received")
|
||||
super.setLabels(msg)
|
||||
}
|
||||
|
||||
override fun markAsDraft(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Draft")
|
||||
super.markAsDraft(msg)
|
||||
}
|
||||
|
||||
override fun markAsSending(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Sending")
|
||||
super.markAsSending(msg)
|
||||
}
|
||||
|
||||
override fun markAsSent(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Sent")
|
||||
super.markAsSent(msg)
|
||||
}
|
||||
|
||||
override fun markAsAcknowledged(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Acknowledged")
|
||||
super.markAsAcknowledged(msg)
|
||||
}
|
||||
|
||||
override fun markAsRead(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Read")
|
||||
super.markAsRead(msg)
|
||||
}
|
||||
|
||||
override fun markAsUnread(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Unread")
|
||||
super.markAsUnread(msg)
|
||||
}
|
||||
|
||||
override fun delete(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Cleared")
|
||||
super.delete(msg)
|
||||
}
|
||||
|
||||
override fun archive(msg: Plaintext) {
|
||||
LOG.info(name + ": From " + name(msg.from) + ": Archived")
|
||||
super.archive(msg)
|
||||
}
|
||||
|
||||
private fun name(address: BitmessageAddress): String {
|
||||
return when {
|
||||
alice == address.address -> "Alice"
|
||||
bob == address.address -> "Bob"
|
||||
else -> "Unknown (" + address.address + ")"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var port = 6000
|
||||
}
|
||||
}
|
@ -15,9 +15,10 @@ dependencies {
|
||||
compile 'org.slf4j:slf4j-api'
|
||||
compile 'com.beust:klaxon'
|
||||
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'org.hamcrest:hamcrest-library'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
|
||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||
testCompile project(':cryptography-bc')
|
||||
}
|
||||
|
@ -19,10 +19,8 @@ package ch.dissem.bitmessage.exports
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.hamcrest.CoreMatchers.`is`
|
||||
import org.hamcrest.CoreMatchers.nullValue
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ContactExportTest {
|
||||
|
||||
@ -42,7 +40,7 @@ class ContactExportTest {
|
||||
)
|
||||
val export = ContactExport.exportContacts(contacts)
|
||||
print(export.toJsonString(true))
|
||||
assertThat(ContactExport.importContacts(export), `is`(contacts))
|
||||
assertEquals(contacts, ContactExport.importContacts(export))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -53,9 +51,9 @@ class ContactExportTest {
|
||||
val export = ContactExport.exportContacts(contacts)
|
||||
print(export.toJsonString(true))
|
||||
val import = ContactExport.importContacts(export)
|
||||
assertThat(import.size, `is`(1))
|
||||
assertThat(import[0].isChan, `is`(true))
|
||||
assertThat(import[0].privateKey, `is`(nullValue()))
|
||||
assertEquals(1, import.size)
|
||||
assertTrue(import[0].isChan)
|
||||
assertNull(import[0].privateKey)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -66,8 +64,9 @@ class ContactExportTest {
|
||||
val export = ContactExport.exportContacts(contacts, true)
|
||||
print(export.toJsonString(true))
|
||||
val import = ContactExport.importContacts(export)
|
||||
assertThat(import.size, `is`(1))
|
||||
assertThat(import[0].isChan, `is`(true))
|
||||
assertThat(import[0].privateKey, `is`(contacts[0].privateKey))
|
||||
|
||||
assertEquals(1, import.size)
|
||||
assertTrue(import[0].isChan)
|
||||
assertEquals(contacts[0].privateKey, import[0].privateKey)
|
||||
}
|
||||
}
|
||||
|
@ -23,23 +23,22 @@ import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
import ch.dissem.bitmessage.utils.ConversationServiceTest
|
||||
import ch.dissem.bitmessage.utils.Singleton
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.hamcrest.CoreMatchers.`is`
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class MessageExportTest {
|
||||
val inbox = Label("Inbox", Label.Type.INBOX, 0x0000ff)
|
||||
val outbox = Label("Outbox", Label.Type.OUTBOX, 0x00ff00)
|
||||
val unread = Label("Unread", Label.Type.UNREAD, 0x000000)
|
||||
val trash = Label("Trash", Label.Type.TRASH, 0x555555)
|
||||
private val inbox = Label("Inbox", Label.Type.INBOX, 0x0000ff)
|
||||
private val outbox = Label("Outbox", Label.Type.OUTBOX, 0x00ff00)
|
||||
private val unread = Label("Unread", Label.Type.UNREAD, 0x000000)
|
||||
private val trash = Label("Trash", Label.Type.TRASH, 0x555555)
|
||||
|
||||
val labels = listOf(
|
||||
private val labels = listOf(
|
||||
inbox,
|
||||
outbox,
|
||||
unread,
|
||||
trash
|
||||
)
|
||||
val labelMap = MessageExport.createLabelMap(labels)
|
||||
private val labelMap = MessageExport.createLabelMap(labels)
|
||||
|
||||
init {
|
||||
TestUtils.mockedInternalContext(cryptography = BouncyCryptography())
|
||||
@ -49,7 +48,7 @@ class MessageExportTest {
|
||||
fun `ensure labels are exported`() {
|
||||
val export = MessageExport.exportLabels(labels)
|
||||
print(export.toJsonString(true))
|
||||
assertThat(MessageExport.importLabels(export), `is`(labels))
|
||||
assertEquals(labels, MessageExport.importLabels(export))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -84,6 +83,6 @@ class MessageExportTest {
|
||||
)
|
||||
val export = MessageExport.exportMessages(messages)
|
||||
print(export.toJsonString(true))
|
||||
assertThat(MessageExport.importMessages(export, labelMap), `is`(messages))
|
||||
assertEquals(messages, MessageExport.importMessages(export, labelMap))
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,10 @@ uploadArchives {
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'org.slf4j:slf4j-simple'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||
testCompile project(':cryptography-bc')
|
||||
}
|
||||
|
@ -21,17 +21,15 @@ import ch.dissem.bitmessage.entity.CustomMessage
|
||||
import ch.dissem.bitmessage.entity.payload.GenericPayload
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.extensions.pow.ProofOfWorkRequest
|
||||
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import ch.dissem.bitmessage.utils.TestBase
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
|
||||
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
class CryptoCustomMessageTest : TestBase() {
|
||||
@Test
|
||||
fun `ensure encrypt then decrypt yields same object`() {
|
||||
@ -40,7 +38,10 @@ class CryptoCustomMessageTest : TestBase() {
|
||||
|
||||
val payloadBefore = GenericPayload(0, 1, cryptography().randomBytes(100))
|
||||
val messageBefore = CryptoCustomMessage(payloadBefore)
|
||||
messageBefore.signAndEncrypt(sendingIdentity, cryptography().createPublicKey(sendingIdentity.publicDecryptionKey))
|
||||
messageBefore.signAndEncrypt(
|
||||
sendingIdentity,
|
||||
cryptography().createPublicKey(sendingIdentity.publicDecryptionKey)
|
||||
)
|
||||
|
||||
val out = ByteArrayOutputStream()
|
||||
messageBefore.writer().write(out)
|
||||
@ -62,11 +63,16 @@ class CryptoCustomMessageTest : TestBase() {
|
||||
val privateKey = PrivateKey.read(TestUtils.getResource("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8.privkey"))
|
||||
val sendingIdentity = BitmessageAddress(privateKey)
|
||||
|
||||
val requestBefore = ProofOfWorkRequest(sendingIdentity, cryptography().randomBytes(64),
|
||||
ProofOfWorkRequest.Request.CALCULATE)
|
||||
val requestBefore = ProofOfWorkRequest(
|
||||
sendingIdentity, cryptography().randomBytes(64),
|
||||
ProofOfWorkRequest.Request.CALCULATE
|
||||
)
|
||||
|
||||
val messageBefore = CryptoCustomMessage(requestBefore)
|
||||
messageBefore.signAndEncrypt(sendingIdentity, cryptography().createPublicKey(sendingIdentity.publicDecryptionKey))
|
||||
messageBefore.signAndEncrypt(
|
||||
sendingIdentity,
|
||||
cryptography().createPublicKey(sendingIdentity.publicDecryptionKey)
|
||||
)
|
||||
|
||||
|
||||
val out = ByteArrayOutputStream()
|
||||
@ -74,8 +80,10 @@ class CryptoCustomMessageTest : TestBase() {
|
||||
val input = ByteArrayInputStream(out.toByteArray())
|
||||
|
||||
val customMessage = CustomMessage.read(input, out.size())
|
||||
val messageAfter = CryptoCustomMessage.read(customMessage,
|
||||
ProofOfWorkRequest.Reader(sendingIdentity))
|
||||
val messageAfter = CryptoCustomMessage.read(
|
||||
customMessage,
|
||||
ProofOfWorkRequest.Reader(sendingIdentity)
|
||||
)
|
||||
val requestAfter = messageAfter.decrypt(sendingIdentity.publicDecryptionKey)
|
||||
|
||||
assertEquals(requestBefore, requestAfter)
|
||||
|
@ -12,9 +12,10 @@ uploadArchives {
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'org.slf4j:slf4j-simple'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||
testCompile project(':cryptography-bc')
|
||||
}
|
||||
|
@ -29,17 +29,11 @@ import ch.dissem.bitmessage.testutils.TestInventory
|
||||
import ch.dissem.bitmessage.utils.Property
|
||||
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import org.hamcrest.Matchers.`is`
|
||||
import org.hamcrest.Matchers.notNullValue
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.DisableOnDebug
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.rules.Timeout
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
/**
|
||||
@ -58,11 +52,7 @@ class NetworkHandlerTest {
|
||||
private lateinit var peerNetworkHandler: NetworkHandler
|
||||
private lateinit var nodeNetworkHandler: NetworkHandler
|
||||
|
||||
@JvmField
|
||||
@Rule
|
||||
val timeout: TestRule = DisableOnDebug(Timeout.seconds(60))
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
peerInventory = TestInventory()
|
||||
peerNetworkHandler = NioNetworkHandler()
|
||||
@ -125,7 +115,7 @@ class NetworkHandlerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
shutdown(peer)
|
||||
shutdown(node)
|
||||
@ -148,8 +138,8 @@ class NetworkHandlerTest {
|
||||
val nodeStatus = waitForNetworkStatus(node)
|
||||
val peerStatus = waitForNetworkStatus(peer)
|
||||
|
||||
assertEquals(1, nodeStatus.getProperty("outgoing")!!.value)
|
||||
assertEquals(1, peerStatus.getProperty("incoming")!!.value)
|
||||
assertEquals(1, nodeStatus.getProperty("outgoing")?.value)
|
||||
assertEquals(1, peerStatus.getProperty("incoming")?.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -161,22 +151,20 @@ class NetworkHandlerTest {
|
||||
|
||||
val response = nodeNetworkHandler.send(peerAddress.toInetAddress(), peerAddress.port, request)
|
||||
|
||||
assertThat(response, notNullValue())
|
||||
assertThat(response.customCommand, `is`("test response"))
|
||||
assertThat(response.getData(), `is`(data))
|
||||
assertNotNull(response)
|
||||
assertEquals("test response", response.customCommand)
|
||||
assertEquals(data, response.getData())
|
||||
}
|
||||
|
||||
@Test(expected = NodeException::class)
|
||||
@Test
|
||||
fun `ensure CustomMessage without response yields exception`() {
|
||||
assertThrows(NodeException::class.java) {
|
||||
val data = cryptography().randomBytes(8)
|
||||
data[0] = 0.toByte()
|
||||
val request = CustomMessage("test request", data)
|
||||
|
||||
val response = nodeNetworkHandler.send(peerAddress.toInetAddress(), peerAddress.port, request)
|
||||
|
||||
assertThat(response, notNullValue())
|
||||
assertThat(response.customCommand, `is`("test response"))
|
||||
assertThat(response.getData(), `is`(request.getData()))
|
||||
nodeNetworkHandler.send(peerAddress.toInetAddress(), peerAddress.port, request)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -13,9 +13,11 @@ uploadArchives {
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'org.flywaydb:flyway-core'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'com.h2database:h2'
|
||||
testCompile 'org.hamcrest:java-hamcrest'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||
testCompile project(':cryptography-bc')
|
||||
}
|
||||
|
@ -19,9 +19,9 @@ package ch.dissem.bitmessage.repository
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class JdbcAddressRepositoryTest : TestBase() {
|
||||
private val CONTACT_A = "BM-2cW7cD5cDQJDNkE7ibmyTxfvGAmnPqa9Vt"
|
||||
@ -34,7 +34,7 @@ class JdbcAddressRepositoryTest : TestBase() {
|
||||
private lateinit var config: TestJdbcConfig
|
||||
private lateinit var repo: JdbcAddressRepository
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
config = TestJdbcConfig()
|
||||
config.reset()
|
||||
|
@ -26,9 +26,9 @@ import ch.dissem.bitmessage.entity.valueobject.InventoryVector
|
||||
import ch.dissem.bitmessage.ports.Inventory
|
||||
import ch.dissem.bitmessage.utils.UnixTime.DAY
|
||||
import ch.dissem.bitmessage.utils.UnixTime.now
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.*
|
||||
|
||||
class JdbcInventoryTest : TestBase() {
|
||||
@ -39,7 +39,7 @@ class JdbcInventoryTest : TestBase() {
|
||||
private lateinit var inventoryVector2: InventoryVector
|
||||
private lateinit var inventoryVectorIgnore: InventoryVector
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
config = TestJdbcConfig()
|
||||
config.reset()
|
||||
|
@ -18,15 +18,15 @@ package ch.dissem.bitmessage.repository
|
||||
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
import ch.dissem.bitmessage.ports.LabelRepository
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class JdbcLabelRepositoryTest : TestBase() {
|
||||
|
||||
private lateinit var repo: LabelRepository
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
val config = TestJdbcConfig()
|
||||
config.reset()
|
||||
|
@ -35,10 +35,12 @@ import org.hamcrest.BaseMatcher
|
||||
import org.hamcrest.CoreMatchers.`is`
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Matcher
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers.*
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.*
|
||||
|
||||
class JdbcMessageRepositoryTest : TestBase() {
|
||||
@ -54,7 +56,7 @@ class JdbcMessageRepositoryTest : TestBase() {
|
||||
private lateinit var drafts: Label
|
||||
private lateinit var unread: Label
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
val config = TestJdbcConfig()
|
||||
config.reset()
|
||||
@ -230,6 +232,7 @@ class JdbcMessageRepositoryTest : TestBase() {
|
||||
val parent = storeConversation()
|
||||
|
||||
val responses = repo.findResponses(parent)
|
||||
|
||||
assertThat(responses, hasSize<Plaintext>(2))
|
||||
assertThat(responses, hasItem(hasMessage("Re: new test", "Nice!")))
|
||||
assertThat(responses, hasItem(hasMessage("Re: new test", "PS: it did work!")))
|
||||
|
@ -19,11 +19,10 @@ package ch.dissem.bitmessage.repository
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress
|
||||
import ch.dissem.bitmessage.ports.NodeRegistry
|
||||
import ch.dissem.bitmessage.utils.UnixTime.now
|
||||
import org.hamcrest.Matchers.empty
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -34,23 +33,25 @@ class JdbcNodeRegistryTest : TestBase() {
|
||||
private lateinit var config: TestJdbcConfig
|
||||
private lateinit var registry: NodeRegistry
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
config = TestJdbcConfig()
|
||||
config.reset()
|
||||
registry = JdbcNodeRegistry(config)
|
||||
|
||||
registry.offerAddresses(Arrays.asList(
|
||||
registry.offerAddresses(
|
||||
Arrays.asList(
|
||||
createAddress(1, 8444, 1, now),
|
||||
createAddress(2, 8444, 1, now),
|
||||
createAddress(3, 8444, 1, now),
|
||||
createAddress(4, 8444, 2, now)
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure getKnownNodes() without streams yields empty`() {
|
||||
assertThat(registry.getKnownAddresses(10), empty<NetworkAddress>())
|
||||
assertTrue(registry.getKnownAddresses(10).isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -71,11 +72,13 @@ class JdbcNodeRegistryTest : TestBase() {
|
||||
|
||||
@Test
|
||||
fun `ensure offered addresses are added`() {
|
||||
registry.offerAddresses(Arrays.asList(
|
||||
registry.offerAddresses(
|
||||
Arrays.asList(
|
||||
createAddress(1, 8444, 1, now),
|
||||
createAddress(10, 8444, 1, now),
|
||||
createAddress(11, 8444, 1, now)
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
var knownAddresses = registry.getKnownAddresses(1000, 1)
|
||||
assertEquals(5, knownAddresses.size.toLong())
|
||||
|
@ -22,9 +22,6 @@ import ch.dissem.bitmessage.entity.Plaintext
|
||||
import ch.dissem.bitmessage.entity.Plaintext.Type.MSG
|
||||
import ch.dissem.bitmessage.entity.payload.GenericPayload
|
||||
import ch.dissem.bitmessage.entity.payload.GetPubkey
|
||||
import ch.dissem.bitmessage.entity.payload.ObjectPayload
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.ports.AddressRepository
|
||||
import ch.dissem.bitmessage.ports.MessageRepository
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkRepository.Item
|
||||
@ -32,11 +29,9 @@ import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import ch.dissem.bitmessage.utils.UnixTime
|
||||
import ch.dissem.bitmessage.utils.UnixTime.MINUTE
|
||||
import org.hamcrest.CoreMatchers.*
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
@ -51,7 +46,7 @@ class JdbcProofOfWorkRepositoryTest : TestBase() {
|
||||
private var initialHash1: ByteArray by Delegates.notNull<ByteArray>()
|
||||
private var initialHash2: ByteArray by Delegates.notNull<ByteArray>()
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
config = TestJdbcConfig()
|
||||
config.reset()
|
||||
@ -66,9 +61,11 @@ class JdbcProofOfWorkRepositoryTest : TestBase() {
|
||||
cryptography = cryptography()
|
||||
)
|
||||
|
||||
repo.putObject(ObjectMessage.Builder()
|
||||
repo.putObject(
|
||||
ObjectMessage.Builder()
|
||||
.payload(GetPubkey(BitmessageAddress("BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn"))).build(),
|
||||
1000, 1000)
|
||||
1000, 1000
|
||||
)
|
||||
initialHash1 = repo.getItems()[0]
|
||||
|
||||
val sender = TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8")
|
||||
@ -84,21 +81,25 @@ class JdbcProofOfWorkRepositoryTest : TestBase() {
|
||||
.build()
|
||||
messageRepo.save(plaintext)
|
||||
initialHash2 = cryptography().getInitialHash(plaintext.ackMessage!!)
|
||||
repo.putObject(Item(
|
||||
repo.putObject(
|
||||
Item(
|
||||
plaintext.ackMessage!!,
|
||||
1000, 1000,
|
||||
UnixTime.now + 10 * MINUTE,
|
||||
plaintext
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure object is stored`() {
|
||||
val sizeBefore = repo.getItems().size
|
||||
repo.putObject(ObjectMessage.Builder()
|
||||
repo.putObject(
|
||||
ObjectMessage.Builder()
|
||||
.payload(GetPubkey(BitmessageAddress("BM-2D9U2hv3YBMHM1zERP32anKfVKohyPN9x2"))).build(),
|
||||
1000, 1000)
|
||||
assertThat(repo.getItems().size, `is`(sizeBefore + 1))
|
||||
1000, 1000
|
||||
)
|
||||
assertEquals(sizeBefore + 1, repo.getItems().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -116,41 +117,43 @@ class JdbcProofOfWorkRepositoryTest : TestBase() {
|
||||
.status(Plaintext.Status.DOING_PROOF_OF_WORK)
|
||||
.build()
|
||||
messageRepo.save(plaintext)
|
||||
repo.putObject(Item(
|
||||
repo.putObject(
|
||||
Item(
|
||||
plaintext.ackMessage!!,
|
||||
1000, 1000,
|
||||
UnixTime.now + 10 * MINUTE,
|
||||
plaintext
|
||||
))
|
||||
assertThat(repo.getItems().size, `is`(sizeBefore + 1))
|
||||
)
|
||||
)
|
||||
assertEquals(sizeBefore + 1, repo.getItems().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure item can be retrieved`() {
|
||||
val item = repo.getItem(initialHash1)
|
||||
assertThat(item, notNullValue())
|
||||
assertThat<ObjectPayload>(item.objectMessage.payload, instanceOf<ObjectPayload>(GetPubkey::class.java))
|
||||
assertThat(item.nonceTrialsPerByte, `is`(1000L))
|
||||
assertThat(item.extraBytes, `is`(1000L))
|
||||
assertTrue(item.objectMessage.payload is GetPubkey)
|
||||
assertEquals(1000L, item.nonceTrialsPerByte)
|
||||
assertEquals(1000L, item.extraBytes)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure ack item can be retrieved`() {
|
||||
val item = repo.getItem(initialHash2)
|
||||
assertThat(item, notNullValue())
|
||||
assertThat<ObjectPayload>(item.objectMessage.payload, instanceOf<ObjectPayload>(GenericPayload::class.java))
|
||||
assertThat(item.nonceTrialsPerByte, `is`(1000L))
|
||||
assertThat(item.extraBytes, `is`(1000L))
|
||||
assertThat(item.expirationTime, not<Number>(0))
|
||||
assertThat(item.message, notNullValue())
|
||||
assertThat<PrivateKey>(item.message?.from?.privateKey, notNullValue())
|
||||
assertThat<Pubkey>(item.message?.to?.pubkey, notNullValue())
|
||||
assertTrue(item.objectMessage.payload is GenericPayload)
|
||||
assertEquals(1000L, item.nonceTrialsPerByte)
|
||||
assertEquals(1000L, item.extraBytes)
|
||||
assertTrue(item.expirationTime ?: 0L > 0L)
|
||||
assertNotNull(item.message)
|
||||
assertNotNull(item.message?.from?.privateKey)
|
||||
assertNotNull(item.message?.to?.pubkey)
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException::class)
|
||||
@Test
|
||||
fun `ensure retrieving nonexisting item causes exception`() {
|
||||
assertThrows(RuntimeException::class.java) {
|
||||
repo.getItem(ByteArray(0))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure item can be deleted`() {
|
||||
|
@ -13,7 +13,8 @@ uploadArchives {
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'org.ini4j:ini4j'
|
||||
testCompile 'junit:junit'
|
||||
testCompile 'com.nhaarman:mockito-kotlin'
|
||||
testCompile 'org.junit.jupiter:junit-jupiter-api'
|
||||
testRuntime 'org.junit.jupiter:junit-jupiter-engine'
|
||||
testCompile project(':cryptography-bc')
|
||||
}
|
||||
|
@ -37,9 +37,10 @@ import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||
import ch.dissem.bitmessage.ports.AddressRepository
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assumptions.assumeTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class WifExporterTest {
|
||||
private val repo = mock<AddressRepository>()
|
||||
@ -47,7 +48,7 @@ class WifExporterTest {
|
||||
private lateinit var importer: WifImporter
|
||||
private lateinit var exporter: WifExporter
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
ctx = BitmessageContext.build {
|
||||
cryptography = BouncyCryptography()
|
||||
@ -61,7 +62,7 @@ class WifExporterTest {
|
||||
listener {}
|
||||
}
|
||||
importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat"))
|
||||
assertEquals(81, importer.getIdentities().size)
|
||||
assumeTrue(importer.getIdentities().size == 81)
|
||||
exporter = WifExporter(ctx)
|
||||
}
|
||||
|
||||
@ -70,10 +71,7 @@ class WifExporterTest {
|
||||
whenever(repo.getIdentities()).thenReturn(importer.getIdentities())
|
||||
exporter.addAll()
|
||||
val result = exporter.toString()
|
||||
var count = 0
|
||||
for (i in 0..result.length - 1) {
|
||||
if (result[i] == '[') count++
|
||||
}
|
||||
val count = result.count { it == '[' }
|
||||
assertEquals(importer.getIdentities().size, count)
|
||||
}
|
||||
|
||||
@ -81,10 +79,7 @@ class WifExporterTest {
|
||||
fun `ensure all from a collection are added`() {
|
||||
exporter.addAll(importer.getIdentities())
|
||||
val result = exporter.toString()
|
||||
var count = 0
|
||||
for (i in 0..result.length - 1) {
|
||||
if (result[i] == '[') count++
|
||||
}
|
||||
val count = result.count { it == '[' }
|
||||
assertEquals(importer.getIdentities().size, count)
|
||||
}
|
||||
|
||||
|
@ -39,16 +39,16 @@ import com.nhaarman.mockito_kotlin.any
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import com.nhaarman.mockito_kotlin.times
|
||||
import com.nhaarman.mockito_kotlin.verify
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class WifImporterTest {
|
||||
private val repo = mock<AddressRepository>()
|
||||
private lateinit var ctx: BitmessageContext
|
||||
private lateinit var importer: WifImporter
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
ctx = BitmessageContext.build {
|
||||
cryptography = BouncyCryptography()
|
||||
@ -81,7 +81,7 @@ class WifImporterTest {
|
||||
assertEquals("Nuked Address", identity.alias)
|
||||
assertEquals(320L, identity.pubkey?.nonceTrialsPerByte)
|
||||
assertEquals(14000L, identity.pubkey?.extraBytes)
|
||||
assertNotNull("Private key", identity.privateKey)
|
||||
assertNotNull(identity.privateKey, "Private key")
|
||||
assertEquals(32, identity.privateKey?.privateEncryptionKey?.size)
|
||||
assertEquals(32, identity.privateKey?.privateSigningKey?.size)
|
||||
assertFalse(identity.isChan)
|
||||
|
Loading…
Reference in New Issue
Block a user