|
|
@ -1,7 +1,8 @@ |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set of tests related to `MemoryAPI` class and the chain of events related to |
|
|
|
* Author: dkanus |
|
|
|
* creating/destroying Acedia's objects / actors. |
|
|
|
* Home repo: https://www.insultplayers.ru/git/AcediaFramework/AcediaCore |
|
|
|
* Copyright 2020-2022 Anton Tarasenko |
|
|
|
* License: GPL |
|
|
|
|
|
|
|
* Copyright 2020-2023 Anton Tarasenko |
|
|
|
*------------------------------------------------------------------------------ |
|
|
|
*------------------------------------------------------------------------------ |
|
|
|
* This file is part of Acedia. |
|
|
|
* This file is part of Acedia. |
|
|
|
* |
|
|
|
* |
|
|
@ -21,8 +22,7 @@ |
|
|
|
class TEST_Memory extends TestCase |
|
|
|
class TEST_Memory extends TestCase |
|
|
|
abstract; |
|
|
|
abstract; |
|
|
|
|
|
|
|
|
|
|
|
protected static function TESTS() |
|
|
|
protected static function TESTS() { |
|
|
|
{ |
|
|
|
|
|
|
|
Test_ObjectConstructorsFinalizers(); |
|
|
|
Test_ObjectConstructorsFinalizers(); |
|
|
|
Test_ActorConstructorsFinalizers(); |
|
|
|
Test_ActorConstructorsFinalizers(); |
|
|
|
Test_ObjectPoolUsage(); |
|
|
|
Test_ObjectPoolUsage(); |
|
|
@ -30,24 +30,21 @@ protected static function TESTS() |
|
|
|
Test_RefCounting(); |
|
|
|
Test_RefCounting(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function Test_LifeVersionIsUnique() |
|
|
|
protected static function Test_LifeVersionIsUnique() { |
|
|
|
{ |
|
|
|
local int i, j; |
|
|
|
local int i, j; |
|
|
|
local int nextVersion; |
|
|
|
local int nextVersion; |
|
|
|
local MockObject obj; |
|
|
|
local MockObject obj; |
|
|
|
local array<int> objectVersions; |
|
|
|
local array<int> objectVersions; |
|
|
|
local bool versionsRepeated; |
|
|
|
local bool versionsRepeated; |
|
|
|
|
|
|
|
// Deallocate and reallocate same object/actor a bunch of times and |
|
|
|
// Deallocate and reallocate same object/actor a bunch of times and |
|
|
|
// ensure that every single time a unique number is returned. |
|
|
|
// ensure that every single time a unique number is returned. |
|
|
|
// Not a comprehensive test of uniqueness, but such is impossible. |
|
|
|
// Not a comprehensive test of uniqueness, but such is impossible. |
|
|
|
for (i = 0; i < 1000 && !versionsRepeated; i += 1) |
|
|
|
for (i = 0; i < 1000 && !versionsRepeated; i += 1) { |
|
|
|
{ |
|
|
|
|
|
|
|
obj = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
obj = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
nextVersion = obj.GetLifeVersion(); |
|
|
|
nextVersion = obj.GetLifeVersion(); |
|
|
|
for (j = 0; j < objectVersions.length; j += 1) |
|
|
|
for (j = 0; j < objectVersions.length; j += 1) { |
|
|
|
{ |
|
|
|
if (nextVersion == objectVersions[j]) { |
|
|
|
if (nextVersion == objectVersions[j]) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
versionsRepeated = true; |
|
|
|
versionsRepeated = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -61,11 +58,10 @@ protected static function Test_LifeVersionIsUnique() |
|
|
|
TEST_ExpectFalse(versionsRepeated); |
|
|
|
TEST_ExpectFalse(versionsRepeated); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function Test_ObjectConstructorsFinalizers() |
|
|
|
protected static function Test_ObjectConstructorsFinalizers() { |
|
|
|
{ |
|
|
|
|
|
|
|
local MockObject obj1, obj2; |
|
|
|
local MockObject obj1, obj2; |
|
|
|
Context("Testing that Acedia object's constructors and finalizers are" |
|
|
|
|
|
|
|
@ "called properly."); |
|
|
|
Context("Testing that Acedia object's constructors and finalizers are called properly."); |
|
|
|
Issue("Object's constructor is not called."); |
|
|
|
Issue("Object's constructor is not called."); |
|
|
|
class'MockObject'.default.objectCount = 0; |
|
|
|
class'MockObject'.default.objectCount = 0; |
|
|
|
obj1 = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
obj1 = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
@ -92,11 +88,10 @@ protected static function Test_ObjectConstructorsFinalizers() |
|
|
|
TEST_ExpectTrue(class'MockObject'.default.objectCount == 0); |
|
|
|
TEST_ExpectTrue(class'MockObject'.default.objectCount == 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function Test_ActorConstructorsFinalizers() |
|
|
|
protected static function Test_ActorConstructorsFinalizers() { |
|
|
|
{ |
|
|
|
|
|
|
|
local MockActor act1, act2; |
|
|
|
local MockActor act1, act2; |
|
|
|
Context("Testing that Acedia actor's constructors and finalizers are" |
|
|
|
|
|
|
|
@ "called properly."); |
|
|
|
Context("Testing that Acedia actor's constructors and finalizers are called properly."); |
|
|
|
Issue("Actor's constructor is not called."); |
|
|
|
Issue("Actor's constructor is not called."); |
|
|
|
act1 = MockActor(__core().GetLevelCore().Allocate(class'MockActor')); |
|
|
|
act1 = MockActor(__core().GetLevelCore().Allocate(class'MockActor')); |
|
|
|
TEST_ExpectTrue(class'MockActor'.default.actorCount == 1); |
|
|
|
TEST_ExpectTrue(class'MockActor'.default.actorCount == 1); |
|
|
@ -115,33 +110,29 @@ protected static function Test_ActorConstructorsFinalizers() |
|
|
|
TEST_ExpectTrue(class'MockActor'.default.actorCount == 0); |
|
|
|
TEST_ExpectTrue(class'MockActor'.default.actorCount == 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function Test_ObjectPoolUsage() |
|
|
|
protected static function Test_ObjectPoolUsage() { |
|
|
|
{ |
|
|
|
local bool allocatedNewObject; |
|
|
|
local bool allocatedNewObject; |
|
|
|
local int i, j; |
|
|
|
local int i, j; |
|
|
|
local MockObject temp; |
|
|
|
local MockObject temp; |
|
|
|
|
|
|
|
local array<MockObject> objects; |
|
|
|
local array<MockObject> objects; |
|
|
|
local MockObjectNoPool obj1, obj2; |
|
|
|
local MockObjectNoPool obj1, obj2; |
|
|
|
|
|
|
|
|
|
|
|
Context("Testing usage of object pools by `MockObject`s."); |
|
|
|
Context("Testing usage of object pools by `MockObject`s."); |
|
|
|
Issue("Object pool is not utilized enough."); |
|
|
|
Issue("Object pool is not utilized enough."); |
|
|
|
for (i = 0; i < 200; i += 1) |
|
|
|
for (i = 0; i < 200; i += 1) { |
|
|
|
{ |
|
|
|
|
|
|
|
objects[objects.length] = |
|
|
|
objects[objects.length] = |
|
|
|
MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
} |
|
|
|
} |
|
|
|
for (i = 0; i < 200; i += 1) { |
|
|
|
for (i = 0; i < 200; i += 1) { |
|
|
|
__().memory.Free(objects[i]); |
|
|
|
__().memory.Free(objects[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
for (i = 0; i < 200; i += 1) |
|
|
|
for (i = 0; i < 200; i += 1) { |
|
|
|
{ |
|
|
|
|
|
|
|
temp = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
temp = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
// Have to find just allocated object among already free ones |
|
|
|
// Have to find just allocated object among already free ones |
|
|
|
j = 0; |
|
|
|
j = 0; |
|
|
|
allocatedNewObject = true; |
|
|
|
allocatedNewObject = true; |
|
|
|
while (j < objects.length) |
|
|
|
while (j < objects.length) { |
|
|
|
{ |
|
|
|
if (objects[j] == temp) { |
|
|
|
if (objects[j] == temp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
allocatedNewObject = false; |
|
|
|
allocatedNewObject = false; |
|
|
|
objects.Remove(j, 1); |
|
|
|
objects.Remove(j, 1); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -161,18 +152,16 @@ protected static function Test_ObjectPoolUsage() |
|
|
|
TEST_ExpectTrue(obj1 != obj2); |
|
|
|
TEST_ExpectTrue(obj1 != obj2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function Test_RefCounting() |
|
|
|
protected static function Test_RefCounting() { |
|
|
|
{ |
|
|
|
|
|
|
|
Context("Testing usage of reference counting."); |
|
|
|
Context("Testing usage of reference counting."); |
|
|
|
SubTest_RefCountingObjectFreeSelf(); |
|
|
|
SubTest_RefCountingObjectFreeSelf(); |
|
|
|
SubTest_RefCountingObjectFree(); |
|
|
|
SubTest_RefCountingObjectFree(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function SubTest_RefCountingObjectFreeSelf() |
|
|
|
protected static function SubTest_RefCountingObjectFreeSelf() { |
|
|
|
{ |
|
|
|
|
|
|
|
local MockObject temp; |
|
|
|
local MockObject temp; |
|
|
|
Issue("Reference counting for `AcediaObject`s does not work correctly" |
|
|
|
|
|
|
|
@ "with `FreeSelf()`"); |
|
|
|
Issue("Reference counting for `AcediaObject`s does not work correctly with `FreeSelf()`"); |
|
|
|
temp = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
temp = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
temp.NewRef().NewRef().NewRef(); |
|
|
|
temp.NewRef().NewRef().NewRef(); |
|
|
|
TEST_ExpectTrue(temp._getRefCount() == 4); |
|
|
|
TEST_ExpectTrue(temp._getRefCount() == 4); |
|
|
@ -191,9 +180,9 @@ protected static function SubTest_RefCountingObjectFreeSelf() |
|
|
|
TEST_ExpectFalse(temp.IsAllocated()); |
|
|
|
TEST_ExpectFalse(temp.IsAllocated()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static function SubTest_RefCountingObjectFree() |
|
|
|
protected static function SubTest_RefCountingObjectFree() { |
|
|
|
{ |
|
|
|
|
|
|
|
local MockObject temp; |
|
|
|
local MockObject temp; |
|
|
|
|
|
|
|
|
|
|
|
Issue("Reference counting for `AcediaObject`s does not work correctly" |
|
|
|
Issue("Reference counting for `AcediaObject`s does not work correctly" |
|
|
|
@ "with `__().memory.Free()`"); |
|
|
|
@ "with `__().memory.Free()`"); |
|
|
|
temp = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
|
temp = MockObject(__().memory.Allocate(class'MockObject')); |
|
|
@ -214,8 +203,7 @@ protected static function SubTest_RefCountingObjectFree() |
|
|
|
TEST_ExpectFalse(temp.IsAllocated()); |
|
|
|
TEST_ExpectFalse(temp.IsAllocated()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
defaultproperties |
|
|
|
defaultproperties { |
|
|
|
{ |
|
|
|
|
|
|
|
caseGroup = "Memory" |
|
|
|
caseGroup = "Memory" |
|
|
|
caseName = "AllocationDeallocation" |
|
|
|
caseName = "AllocationDeallocation" |
|
|
|
} |
|
|
|
} |