Adjust test expectations for the new MM
This commit is contained in:
committed by
Space
parent
f2a067eda0
commit
e0c7cda1cf
@@ -54,6 +54,34 @@ fun testCleanerLambda() {
|
|||||||
assertNull(funBoxWeak!!.value)
|
assertNull(funBoxWeak!!.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCleanerNonSharedLambda() {
|
||||||
|
// Only for experimental MM.
|
||||||
|
if (Platform.memoryModel != MemoryModel.EXPERIMENTAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val called = AtomicBoolean(false);
|
||||||
|
var funBoxWeak: WeakReference<FunBox>? = null
|
||||||
|
var cleanerWeak: WeakReference<Cleaner>? = null
|
||||||
|
{
|
||||||
|
val cleaner = {
|
||||||
|
val funBox = FunBox { called.value = true }
|
||||||
|
funBoxWeak = WeakReference(funBox)
|
||||||
|
createCleaner(funBox) { it.call() }
|
||||||
|
}()
|
||||||
|
GC.collect() // Make sure local funBox reference is gone
|
||||||
|
cleanerWeak = WeakReference(cleaner)
|
||||||
|
assertFalse(called.value)
|
||||||
|
}()
|
||||||
|
|
||||||
|
GC.collect()
|
||||||
|
performGCOnCleanerWorker()
|
||||||
|
|
||||||
|
assertNull(cleanerWeak!!.value)
|
||||||
|
assertTrue(called.value)
|
||||||
|
assertNull(funBoxWeak!!.value)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCleanerAnonymousFunction() {
|
fun testCleanerAnonymousFunction() {
|
||||||
val called = AtomicBoolean(false);
|
val called = AtomicBoolean(false);
|
||||||
@@ -78,6 +106,34 @@ fun testCleanerAnonymousFunction() {
|
|||||||
assertNull(funBoxWeak!!.value)
|
assertNull(funBoxWeak!!.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCleanerNonSharedAnonymousFunction() {
|
||||||
|
// Only for experimental MM.
|
||||||
|
if (Platform.memoryModel != MemoryModel.EXPERIMENTAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val called = AtomicBoolean(false);
|
||||||
|
var funBoxWeak: WeakReference<FunBox>? = null
|
||||||
|
var cleanerWeak: WeakReference<Cleaner>? = null
|
||||||
|
{
|
||||||
|
val cleaner = {
|
||||||
|
val funBox = FunBox { called.value = true }
|
||||||
|
funBoxWeak = WeakReference(funBox)
|
||||||
|
createCleaner(funBox, fun (it: FunBox) { it.call() })
|
||||||
|
}()
|
||||||
|
GC.collect() // Make sure local funBox reference is gone
|
||||||
|
cleanerWeak = WeakReference(cleaner)
|
||||||
|
assertFalse(called.value)
|
||||||
|
}()
|
||||||
|
|
||||||
|
GC.collect()
|
||||||
|
performGCOnCleanerWorker()
|
||||||
|
|
||||||
|
assertNull(cleanerWeak!!.value)
|
||||||
|
assertTrue(called.value)
|
||||||
|
assertNull(funBoxWeak!!.value)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCleanerFunctionReference() {
|
fun testCleanerFunctionReference() {
|
||||||
val called = AtomicBoolean(false);
|
val called = AtomicBoolean(false);
|
||||||
@@ -102,8 +158,40 @@ fun testCleanerFunctionReference() {
|
|||||||
assertNull(funBoxWeak!!.value)
|
assertNull(funBoxWeak!!.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCleanerNonSharedFunctionReference() {
|
||||||
|
// Only for experimental MM.
|
||||||
|
if (Platform.memoryModel != MemoryModel.EXPERIMENTAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val called = AtomicBoolean(false);
|
||||||
|
var funBoxWeak: WeakReference<FunBox>? = null
|
||||||
|
var cleanerWeak: WeakReference<Cleaner>? = null
|
||||||
|
{
|
||||||
|
val cleaner = {
|
||||||
|
val funBox = FunBox { called.value = true }
|
||||||
|
funBoxWeak = WeakReference(funBox)
|
||||||
|
createCleaner(funBox, FunBox::call)
|
||||||
|
}()
|
||||||
|
GC.collect() // Make sure local funBox reference is gone
|
||||||
|
cleanerWeak = WeakReference(cleaner)
|
||||||
|
assertFalse(called.value)
|
||||||
|
}()
|
||||||
|
|
||||||
|
GC.collect()
|
||||||
|
performGCOnCleanerWorker()
|
||||||
|
|
||||||
|
assertNull(cleanerWeak!!.value)
|
||||||
|
assertTrue(called.value)
|
||||||
|
assertNull(funBoxWeak!!.value)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCleanerFailWithNonShareableArgument() {
|
fun testCleanerFailWithNonShareableArgument() {
|
||||||
|
// Only for legacy MM.
|
||||||
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
val funBox = FunBox {}
|
val funBox = FunBox {}
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
createCleaner(funBox) {}
|
createCleaner(funBox) {}
|
||||||
|
|||||||
@@ -37,20 +37,30 @@ fun testGlobal() {
|
|||||||
val global2: WorkerBoundReference<A> = WorkerBoundReference(A(3))
|
val global2: WorkerBoundReference<A> = WorkerBoundReference(A(3))
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testGlobalDenyAccessOnWorker() {
|
fun testGlobalAccessOnWorker() {
|
||||||
assertEquals(3, global2.value.a)
|
assertEquals(3, global2.value.a)
|
||||||
|
|
||||||
val worker = Worker.start()
|
val worker = Worker.start()
|
||||||
val future = worker.execute(TransferMode.SAFE, {}) {
|
val future = worker.execute(TransferMode.SAFE, {}) {
|
||||||
val local = global2
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
assertFailsWith<IncorrectDereferenceException> {
|
assertEquals(global2.value, global2.valueOrNull)
|
||||||
local.value
|
global2.value.a
|
||||||
|
} else {
|
||||||
|
val local = global2
|
||||||
|
assertFailsWith<IncorrectDereferenceException> {
|
||||||
|
local.value
|
||||||
|
}
|
||||||
|
assertEquals(null, local.valueOrNull)
|
||||||
|
null
|
||||||
}
|
}
|
||||||
assertEquals(null, local.valueOrNull)
|
|
||||||
Unit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
future.result
|
val value = future.result
|
||||||
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
assertEquals(3, value)
|
||||||
|
} else {
|
||||||
|
assertEquals(null, value)
|
||||||
|
}
|
||||||
worker.requestTermination().result
|
worker.requestTermination().result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,20 +199,30 @@ fun testLocalFrozen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testLocalDenyAccessOnWorkerFrozen() {
|
fun testLocalAccessOnWorkerFrozen() {
|
||||||
val local = WorkerBoundReference(A(3)).freeze()
|
val local = WorkerBoundReference(A(3)).freeze()
|
||||||
assertEquals(3, local.value.a)
|
assertEquals(3, local.value.a)
|
||||||
|
|
||||||
val worker = Worker.start()
|
val worker = Worker.start()
|
||||||
val future = worker.execute(TransferMode.SAFE, { local }) { local ->
|
val future = worker.execute(TransferMode.SAFE, { local }) { local ->
|
||||||
assertFailsWith<IncorrectDereferenceException> {
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
local.value
|
assertEquals(local.value, local.valueOrNull)
|
||||||
|
local.value.a
|
||||||
|
} else {
|
||||||
|
assertFailsWith<IncorrectDereferenceException> {
|
||||||
|
local.value
|
||||||
|
}
|
||||||
|
assertEquals(null, local.valueOrNull)
|
||||||
|
null
|
||||||
}
|
}
|
||||||
assertEquals(null, local.valueOrNull)
|
|
||||||
Unit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
future.result
|
val value = future.result
|
||||||
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
assertEquals(3, value)
|
||||||
|
} else {
|
||||||
|
assertEquals(null, value)
|
||||||
|
}
|
||||||
worker.requestTermination().result
|
worker.requestTermination().result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,17 +297,22 @@ fun testLocalAccessOnMainThread() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testLocalDenyAccessOnMainThreadFrozen() {
|
fun testLocalAccessOnMainThreadFrozen() {
|
||||||
val worker = Worker.start()
|
val worker = Worker.start()
|
||||||
val future = worker.execute(TransferMode.SAFE, {}) {
|
val future = worker.execute(TransferMode.SAFE, {}) {
|
||||||
WorkerBoundReference(A(3)).freeze()
|
WorkerBoundReference(A(3)).freeze()
|
||||||
}
|
}
|
||||||
|
|
||||||
val value = future.result
|
val value = future.result
|
||||||
assertFailsWith<IncorrectDereferenceException> {
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
value.value
|
assertEquals(3, value.value.a)
|
||||||
|
assertEquals(value.value, value.valueOrNull)
|
||||||
|
} else {
|
||||||
|
assertFailsWith<IncorrectDereferenceException> {
|
||||||
|
value.value
|
||||||
|
}
|
||||||
|
assertEquals(null, value.valueOrNull)
|
||||||
}
|
}
|
||||||
assertEquals(null, value.valueOrNull)
|
|
||||||
|
|
||||||
worker.requestTermination().result
|
worker.requestTermination().result
|
||||||
}
|
}
|
||||||
@@ -385,20 +410,30 @@ fun testLocalWithWrapperFrozen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testLocalDenyAccessWithWrapperFrozen() {
|
fun testLocalAccessWithWrapperFrozen() {
|
||||||
val local = Wrapper(WorkerBoundReference(A(3))).freeze()
|
val local = Wrapper(WorkerBoundReference(A(3))).freeze()
|
||||||
assertEquals(3, local.ref.value.a)
|
assertEquals(3, local.ref.value.a)
|
||||||
|
|
||||||
val worker = Worker.start()
|
val worker = Worker.start()
|
||||||
val future = worker.execute(TransferMode.SAFE, { local }) { local ->
|
val future = worker.execute(TransferMode.SAFE, { local }) { local ->
|
||||||
assertFailsWith<IncorrectDereferenceException> {
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
local.ref.value
|
assertEquals(local.ref.value, local.ref.valueOrNull)
|
||||||
|
local.ref.value.a
|
||||||
|
} else {
|
||||||
|
assertFailsWith<IncorrectDereferenceException> {
|
||||||
|
local.ref.value
|
||||||
|
}
|
||||||
|
assertEquals(null, local.ref.valueOrNull)
|
||||||
|
null
|
||||||
}
|
}
|
||||||
assertEquals(null, local.ref.valueOrNull)
|
|
||||||
Unit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
future.result
|
val value = future.result
|
||||||
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
assertEquals(3, value)
|
||||||
|
} else {
|
||||||
|
assertEquals(null, value)
|
||||||
|
}
|
||||||
worker.requestTermination().result
|
worker.requestTermination().result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +472,14 @@ fun testCollectFrozen() {
|
|||||||
val (refOwner, refWeak, refValueWeak) = getOwnerAndWeaksFrozen(3)
|
val (refOwner, refWeak, refValueWeak) = getOwnerAndWeaksFrozen(3)
|
||||||
|
|
||||||
refOwner.value = null
|
refOwner.value = null
|
||||||
GC.collect()
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
// This runs the finalizer on the WorkerBoundReference<A>, which schedules removing A from the root set
|
||||||
|
GC.collect()
|
||||||
|
// This actually frees A
|
||||||
|
GC.collect()
|
||||||
|
} else {
|
||||||
|
GC.collect()
|
||||||
|
}
|
||||||
|
|
||||||
// Last reference to WorkerBoundReference is gone, so it and it's referent are destroyed.
|
// Last reference to WorkerBoundReference is gone, so it and it's referent are destroyed.
|
||||||
assertNull(refWeak.value)
|
assertNull(refWeak.value)
|
||||||
@@ -647,7 +689,16 @@ fun collectCyclicGarbageWithAtomicsFrozen() {
|
|||||||
val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageWithAtomicsFrozen()
|
val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageWithAtomicsFrozen()
|
||||||
|
|
||||||
dispose(ref1Owner)
|
dispose(ref1Owner)
|
||||||
GC.collect()
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
// Finalizes WorkerBoundReference<C2> and schedules C2 removal from the root set
|
||||||
|
GC.collect()
|
||||||
|
// Frees C2, finalizes WorkerBoundReference<C1> and schedules C1 removal from the root set
|
||||||
|
GC.collect()
|
||||||
|
// Frees C1
|
||||||
|
GC.collect()
|
||||||
|
} else {
|
||||||
|
GC.collect()
|
||||||
|
}
|
||||||
|
|
||||||
assertNull(ref1Weak.value)
|
assertNull(ref1Weak.value)
|
||||||
assertNull(ref2Weak.value)
|
assertNull(ref2Weak.value)
|
||||||
@@ -723,16 +774,25 @@ fun concurrentAccessFrozen() {
|
|||||||
while (workerUnlocker.value < 1) {
|
while (workerUnlocker.value < 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assertFailsWith<IncorrectDereferenceException> {
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
ref.value
|
ref.value.a
|
||||||
|
} else {
|
||||||
|
assertFailsWith<IncorrectDereferenceException> {
|
||||||
|
ref.value
|
||||||
|
}
|
||||||
|
null
|
||||||
}
|
}
|
||||||
Unit
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
workerUnlocker.increment()
|
workerUnlocker.increment()
|
||||||
|
|
||||||
for (future in futures) {
|
for (future in futures) {
|
||||||
future.result
|
val value = future.result
|
||||||
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
assertEquals(3, value)
|
||||||
|
} else {
|
||||||
|
assertEquals(null, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (worker in workers) {
|
for (worker in workers) {
|
||||||
@@ -742,6 +802,11 @@ fun concurrentAccessFrozen() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testExceptionMessageFrozen() {
|
fun testExceptionMessageFrozen() {
|
||||||
|
// Only for legacy MM
|
||||||
|
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val worker = Worker.start()
|
val worker = Worker.start()
|
||||||
val future = worker.execute(TransferMode.SAFE, {}) {
|
val future = worker.execute(TransferMode.SAFE, {}) {
|
||||||
WorkerBoundReference(A(3)).freeze()
|
WorkerBoundReference(A(3)).freeze()
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ val topSharedData = Data(43)
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}).consume {
|
}).consume {
|
||||||
result -> assertEquals(Platform.memoryModel == MemoryModel.RELAXED, result)
|
result -> assertEquals(Platform.memoryModel != MemoryModel.STRICT, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
worker.execute(TransferMode.SAFE, { -> }, {
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
@@ -65,7 +65,7 @@ val topSharedData = Data(43)
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}).consume {
|
}).consume {
|
||||||
result -> assertEquals(Platform.memoryModel == MemoryModel.RELAXED, result)
|
result -> assertEquals(Platform.memoryModel != MemoryModel.STRICT, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
worker.execute(TransferMode.SAFE, { -> }, {
|
worker.execute(TransferMode.SAFE, { -> }, {
|
||||||
@@ -181,4 +181,4 @@ val atomicRef2 = AtomicReference<Any?>(Any().freeze())
|
|||||||
semaphore.increment()
|
semaphore.increment()
|
||||||
future.result
|
future.result
|
||||||
worker.requestTermination().result
|
worker.requestTermination().result
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user