From c4bf05fd9d0126cbdf4db09f11bc5737b38f5f76 Mon Sep 17 00:00:00 2001
From: Ivan Mogilko <[EMAIL REDACTED]>
Date: Fri, 13 Oct 2023 19:43:18 +0300
Subject: [PATCH] Added subsystem refcount tests to testautomation
---
.../testautomation/testautomation.vcxproj | 3 +-
test/testautomation.c | 1 +
test/testautomation_subsystems.c | 239 ++++++++++++++++++
test/testautomation_suites.h | 1 +
4 files changed, 243 insertions(+), 1 deletion(-)
create mode 100644 test/testautomation_subsystems.c
diff --git a/VisualC/tests/testautomation/testautomation.vcxproj b/VisualC/tests/testautomation/testautomation.vcxproj
index fd1f86c9b3f4..f64b89be8db2 100644
--- a/VisualC/tests/testautomation/testautomation.vcxproj
+++ b/VisualC/tests/testautomation/testautomation.vcxproj
@@ -221,6 +221,7 @@
<ClCompile Include="..\..\..\test\testautomation_syswm.c" />
<ClCompile Include="..\..\..\test\testautomation_timer.c" />
<ClCompile Include="..\..\..\test\testautomation_video.c" />
+ <ClCompile Include="..\..\..\test\testautomation_subsystems.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\test\testautomation_suites.h" />
@@ -228,4 +229,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/test/testautomation.c b/test/testautomation.c
index 8e5f002fe5c3..7cdd6be9337a 100644
--- a/test/testautomation.c
+++ b/test/testautomation.c
@@ -45,6 +45,7 @@ static SDLTest_TestSuiteReference *testSuites[] = {
&syswmTestSuite,
&timerTestSuite,
&videoTestSuite,
+ &subsystemsTestSuite, /* run last, not interfere with other test enviroment */
NULL
};
diff --git a/test/testautomation_subsystems.c b/test/testautomation_subsystems.c
new file mode 100644
index 000000000000..1bbc6410da1a
--- /dev/null
+++ b/test/testautomation_subsystems.c
@@ -0,0 +1,239 @@
+/**
+ * Events test suite
+ */
+#include "testautomation_suites.h"
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_test.h>
+
+/* ================= Test Case Implementation ================== */
+
+/* Fixture */
+
+static void subsystemsSetUp(void *arg)
+{
+ /* Reset each one of the SDL subsystems */
+ /* CHECKME: can we use SDL_Quit here, or this will break the flow of tests? */
+ SDL_Quit();
+ /* Alternate variant without SDL_Quit:
+ while (SDL_WasInit(SDL_INIT_EVERYTHING) != 0) {
+ SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
+ }
+ */
+ SDLTest_AssertPass("Reset all subsystems before subsystems test");
+ SDLTest_AssertCheck(SDL_WasInit(SDL_INIT_EVERYTHING) == 0, "Check result from SDL_WasInit(SDL_INIT_EVERYTHING)");
+}
+
+static void subsystemsTearDown(void *arg)
+{
+ /* Reset each one of the SDL subsystems */
+ SDL_Quit();
+
+ SDLTest_AssertPass("Cleanup of subsystems test completed");
+}
+
+/* Test case functions */
+
+/**
+ * \brief Inits and Quits particular subsystem, checking its Init status.
+ *
+ * \sa SDL_InitSubSystem
+ * \sa SDL_QuitSubSystem
+ *
+ */
+static int subsystems_referenceCount()
+{
+ const int system = SDL_INIT_VIDEO;
+ int result;
+ /* Ensure that we start with a non-initialized subsystem. */
+ SDLTest_AssertCheck(SDL_WasInit(system) == 0, "Check result from SDL_WasInit(0x%x)", system);
+
+ /* Init subsystem once, and quit once */
+ SDL_InitSubSystem(system);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(0x%x)", system);
+ result = SDL_WasInit(system);
+ SDLTest_AssertCheck(result == system, "Check result from SDL_WasInit(0x%x), expected: 0x%x, got: 0x%x", system, system, result);
+
+ SDL_QuitSubSystem(system);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(0x%x)", system);
+ result = SDL_WasInit(system);
+ SDLTest_AssertCheck(result == 0, "Check result from SDL_WasInit(0x%x), expected: 0, got: 0x%x", system, result);
+
+ /* Init subsystem number of times, then decrement reference count until it's disposed of. */
+ SDL_InitSubSystem(system);
+ SDL_InitSubSystem(system);
+ SDL_InitSubSystem(system);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(0x%x) x3 times", system);
+ result = SDL_WasInit(system);
+ SDLTest_AssertCheck(result == system, "Check result from SDL_WasInit(0x%x), expected: 0x%x, got: 0x%x", system, system, result);
+
+ SDL_QuitSubSystem(system);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(0x%x) x1", system);
+ result = SDL_WasInit(system);
+ SDLTest_AssertCheck(result == system, "Check result from SDL_WasInit(0x%x), expected: 0x%x, got: 0x%x", system, system, result);
+ SDL_QuitSubSystem(system);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(0x%x) x2", system);
+ result = SDL_WasInit(system);
+ SDLTest_AssertCheck(result == system, "Check result from SDL_WasInit(0x%x), expected: 0x%x, got: 0x%x", system, system, result);
+ SDL_QuitSubSystem(system);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(0x%x) x3", system);
+ result = SDL_WasInit(system);
+ SDLTest_AssertCheck(result == 0, "Check result from SDL_WasInit(0x%x), expected: 0, got: 0x%x", system, result);
+
+ return TEST_COMPLETED;
+}
+
+/**
+ * \brief Inits and Quits subsystems that have another as dependency;
+ * check that the dependency is not removed before the last of its dependents.
+ *
+ * \sa SDL_InitSubSystem
+ * \sa SDL_QuitSubSystem
+ *
+ */
+static int subsystems_dependRefCountInitAllQuitByOne()
+{
+ int result;
+ /* Ensure that we start with reset subsystems. */
+ SDLTest_AssertCheck(SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS) == 0,
+ "Check result from SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS)");
+
+ /* Following should init SDL_INIT_EVENTS and give it +3 ref counts. */
+ SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+
+ /* Quit systems one by one. */
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_VIDEO)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_JOYSTICK)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == 0, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0, got: 0x%x", result);
+
+ return TEST_COMPLETED;
+}
+
+/**
+ * \brief Inits and Quits subsystems that have another as dependency;
+ * check that the dependency is not removed before the last of its dependents.
+ *
+ * \sa SDL_InitSubSystem
+ * \sa SDL_QuitSubSystem
+ *
+ */
+static int subsystems_dependRefCountInitByOneQuitAll()
+{
+ int result;
+ /* Ensure that we start with reset subsystems. */
+ SDLTest_AssertCheck(SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS) == 0,
+ "Check result from SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS)");
+
+ /* Following should init SDL_INIT_EVENTS and give it +3 ref counts. */
+ SDL_InitSubSystem(SDL_INIT_VIDEO);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_VIDEO)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+ SDL_InitSubSystem(SDL_INIT_AUDIO);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)");
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_JOYSTICK)");
+
+ /* Quit systems all at once. */
+ SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == 0, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0, got: 0x%x", result);
+
+ return TEST_COMPLETED;
+}
+
+/**
+ * \brief Inits and Quits subsystems that have another as dependency,
+ * but also inits that dependency explicitly, giving it extra ref count.
+ * Check that the dependency is not removed before the last reference is gone.
+ *
+ * \sa SDL_InitSubSystem
+ * \sa SDL_QuitSubSystem
+ *
+ */
+static int subsystems_dependRefCountWithExtraInit()
+{
+ int result;
+ /* Ensure that we start with reset subsystems. */
+ SDLTest_AssertCheck(SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS) == 0,
+ "Check result from SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS)");
+
+ /* Init EVENTS explicitly, +1 ref count. */
+ SDL_InitSubSystem(SDL_INIT_EVENTS);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_EVENTS)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+ /* Following should init SDL_INIT_EVENTS and give it +3 ref counts. */
+ SDL_InitSubSystem(SDL_INIT_VIDEO);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_VIDEO)");
+ SDL_InitSubSystem(SDL_INIT_AUDIO);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)");
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_JOYSTICK)");
+
+ /* Quit EVENTS explicitly, -1 ref count. */
+ SDL_QuitSubSystem(SDL_INIT_EVENTS);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_EVENTS)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+
+ /* Quit systems one by one. */
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_VIDEO)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == SDL_INIT_EVENTS, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0x4000, got: 0x%x", result);
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_JOYSTICK)");
+ result = SDL_WasInit(SDL_INIT_EVENTS);
+ SDLTest_AssertCheck(result == 0, "Check result from SDL_WasInit(SDL_INIT_EVENTS), expected: 0, got: 0x%x", result);
+
+ return TEST_COMPLETED;
+}
+
+/* ================= Test References ================== */
+
+/* Subsystems test cases */
+static const SDLTest_TestCaseReference subsystemsTest1 = {
+ (SDLTest_TestCaseFp)subsystems_referenceCount, "subsystems_referenceCount", "Makes sure that subsystem stays until number of quits matches inits.", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference subsystemsTest2 = {
+ (SDLTest_TestCaseFp)subsystems_dependRefCountInitAllQuitByOne, "subsystems_dependRefCountInitAllQuitByOne", "Check reference count of subsystem dependencies.", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference subsystemsTest3 = {
+ (SDLTest_TestCaseFp)subsystems_dependRefCountInitByOneQuitAll, "subsystems_dependRefCountInitByOneQuitAll", "Check reference count of subsystem dependencies.", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference subsystemsTest4 = {
+ (SDLTest_TestCaseFp)subsystems_dependRefCountWithExtraInit, "subsystems_dependRefCountWithExtraInit", "Check reference count of subsystem dependencies.", TEST_ENABLED
+};
+
+/* Sequence of Events test cases */
+static const SDLTest_TestCaseReference *subsystemsTests[] = {
+ &subsystemsTest1, &subsystemsTest2, &subsystemsTest3, &subsystemsTest4, NULL
+};
+
+/* Events test suite (global) */
+SDLTest_TestSuiteReference subsystemsTestSuite = {
+ "Subsystems",
+ subsystemsSetUp,
+ subsystemsTests,
+ subsystemsTearDown
+};
diff --git a/test/testautomation_suites.h b/test/testautomation_suites.h
index e1a29e0b70e2..9a562620a2d0 100644
--- a/test/testautomation_suites.h
+++ b/test/testautomation_suites.h
@@ -28,6 +28,7 @@ extern SDLTest_TestSuiteReference renderTestSuite;
extern SDLTest_TestSuiteReference rwopsTestSuite;
extern SDLTest_TestSuiteReference sdltestTestSuite;
extern SDLTest_TestSuiteReference stdlibTestSuite;
+extern SDLTest_TestSuiteReference subsystemsTestSuite;
extern SDLTest_TestSuiteReference surfaceTestSuite;
extern SDLTest_TestSuiteReference syswmTestSuite;
extern SDLTest_TestSuiteReference timerTestSuite;