forked from sergeych/crypto2
fixed tests. better atomic operations
This commit is contained in:
parent
ce8cfe8e3d
commit
b86c7a853e
6
.idea/GitLink.xml
generated
Normal file
6
.idea/GitLink.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="uk.co.ben_gibson.git.link.SettingsState">
|
||||||
|
<option name="host" value="e0f86390-1091-4871-8aeb-f534fbc99cf0" />
|
||||||
|
</component>
|
||||||
|
</project>
|
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
@ -7,7 +7,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "0.1.0-SNAPSHOT"
|
version = "0.1.1-SNAPSHOT"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
package net.sergeych.tools
|
package net.sergeych.tools
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class AtomicCounter(initialValue: Long = 0) {
|
class AtomicCounter(initialValue: Long = 0) : AtomicValue<Long>(initialValue) {
|
||||||
private val op = ProtectedOp()
|
fun incrementAndGet(): Long = mutate { it+1 }
|
||||||
var value: Long = initialValue
|
|
||||||
private set
|
|
||||||
|
|
||||||
fun incrementAndGet(): Long = op { ++value }
|
|
||||||
}
|
}
|
35
src/commonMain/kotlin/net/sergeych/tools/AtomicValue.kt
Normal file
35
src/commonMain/kotlin/net/sergeych/tools/AtomicValue.kt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package net.sergeych.tools
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplatform (JS and battery included) atomically mutable value.
|
||||||
|
* Actual value can be either changed in a block of [mutuate] when
|
||||||
|
* new value _depends on the current value_ or use a same [value]
|
||||||
|
* property that is thread-safe where there are threads and just safe
|
||||||
|
* otherwise ;)
|
||||||
|
*/
|
||||||
|
open class AtomicValue<T>(initialValue: T) {
|
||||||
|
var actualValue = initialValue
|
||||||
|
val op = ProtectedOp()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the value: get the current and set to the returned, all in the
|
||||||
|
* atomic operation. All other mutating requests including assigning to [value]
|
||||||
|
* will be blocked and queued.
|
||||||
|
* @return result of the mutation. Note that immediate call to property [value]
|
||||||
|
* could already return modified bu some other thread value!
|
||||||
|
*/
|
||||||
|
fun mutate(mutator: (T) -> T): T = op {
|
||||||
|
actualValue = mutator(actualValue)
|
||||||
|
actualValue
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic get or set the value. Atomic get means if there is a [mutate] in progress
|
||||||
|
* it will wait until the mutation finishes and then return the correct result.
|
||||||
|
*/
|
||||||
|
var value: T
|
||||||
|
get() = op { actualValue }
|
||||||
|
set(value) {
|
||||||
|
mutate { value }
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,7 @@ class KeysTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testCreationAndMap() = runTest {
|
fun testCreationAndMap() = runTest {
|
||||||
initCrypto()
|
initCrypto()
|
||||||
val (stk,pbk) = SigningKey.Secret.pair()
|
val (stk,pbk) = SigningKey.pair()
|
||||||
|
|
||||||
val x = mapOf( stk to "STK!", pbk to "PBK!")
|
val x = mapOf( stk to "STK!", pbk to "PBK!")
|
||||||
assertEquals("STK!", x[stk])
|
assertEquals("STK!", x[stk])
|
||||||
@ -27,17 +27,17 @@ class KeysTest {
|
|||||||
|
|
||||||
data1[0] = 0x01u
|
data1[0] = 0x01u
|
||||||
assertFalse(s.verify(data1))
|
assertFalse(s.verify(data1))
|
||||||
val p2 = SigningKey.Secret.pair()
|
val p2 = SigningKey.pair()
|
||||||
val p3 = SigningKey.Secret.pair()
|
val p3 = SigningKey.pair()
|
||||||
|
|
||||||
val ms = SignedBox(data, s1) + p2.signing
|
val ms = SignedBox(data, s1) + p2.secretKey
|
||||||
|
|
||||||
// non tampered:
|
// non tampered:
|
||||||
val ms1 = unpack<SignedBox>(pack(ms))
|
val ms1 = unpack<SignedBox>(pack(ms))
|
||||||
assertContentEquals(data, ms1.message)
|
assertContentEquals(data, ms1.message)
|
||||||
assertTrue(pbk in ms1)
|
assertTrue(pbk in ms1)
|
||||||
assertTrue(p2.aPublic in ms1)
|
assertTrue(p2.publicKey in ms1)
|
||||||
assertTrue(p3.aPublic !in ms1)
|
assertTrue(p3.publicKey !in ms1)
|
||||||
|
|
||||||
assertThrows<IllegalSignatureException> {
|
assertThrows<IllegalSignatureException> {
|
||||||
unpack<SignedBox>(pack(ms).also { it[3] = 1u })
|
unpack<SignedBox>(pack(ms).also { it[3] = 1u })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user