Skip to content

Add standalone unit tests and CI workflow for Unreal GSDK#194

Closed
Copilot wants to merge 6 commits into
mainfrom
copilot/add-unit-tests-gsdk
Closed

Add standalone unit tests and CI workflow for Unreal GSDK#194
Copilot wants to merge 6 commits into
mainfrom
copilot/add-unit-tests-gsdk

Conversation

Copilot AI commented Mar 3, 2026

Copy link
Copy Markdown
Contributor
  • Add standalone C++ unit tests for Unreal GSDK (CMake + Google Test + nlohmann/json)
  • Add CI workflow .github/workflows/unreal-tests.yml for PRs affecting UnrealPlugin/**
  • Add "Plugin files" section to UnrealPlugin/README.md clarifying which files are needed for integration
  • Update UnrealPlugin/ThirdPersonMPGSDKSetup.md to list specific files to copy
  • Rebase onto latest origin/main

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add unit tests for Unreal GSDK Add standalone unit tests and CI workflow for Unreal GSDK Mar 3, 2026
@dgkanatsios

Copy link
Copy Markdown
Contributor

@copilot can you amend the Unreal README to mention that these files are not needed, when someone uses the Unreal GSDK?

Copilot AI commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot can you amend the Unreal README to mention that these files are not needed, when someone uses the Unreal GSDK?

Added a "Directory structure" section to UnrealPlugin/README.md in 9eb3025 that lists the three files/directories needed for integration (Source/, Resources/, PlayFabGSDK.uplugin) and clarifies that Tests/, TestingProject/, Documentation/, docs, and license files are not needed for game projects.

@dgkanatsios

Copy link
Copy Markdown
Contributor

@copilot can you try again?

Copilot AI commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot can you try again?

Revised the README section in f18d845 — renamed to "Plugin files" with a clearer note callout, and also updated ThirdPersonMPGSDKSetup.md to list the specific files to copy (Source/, Resources/, PlayFabGSDK.uplugin) instead of "drag all files."

@dgkanatsios dgkanatsios marked this pull request as ready for review March 5, 2026 01:03
@dgkanatsios

Copy link
Copy Markdown
Contributor

@copilot can you rebase?

@dgkanatsios

Copy link
Copy Markdown
Contributor

@copilot can you rebase?

Copilot AI commented Mar 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot can you rebase?

Rebased onto latest origin/main (ba9b01f) in 97b0ef1.

Copilot AI and others added 6 commits March 19, 2026 10:27
Co-authored-by: dgkanatsios <8256138+dgkanatsios@users.noreply.github.com>
…es are needed

Co-authored-by: dgkanatsios <8256138+dgkanatsios@users.noreply.github.com>
…ecific files to copy

Co-authored-by: dgkanatsios <8256138+dgkanatsios@users.noreply.github.com>
* Initial plan

* Initial plan for Java GSDK unit tests

Co-authored-by: dgkanatsios <8256138+dgkanatsios@users.noreply.github.com>

* Add Java GSDK unit tests and CI workflow

Add 84 unit tests across 8 test classes covering:
- ConnectedPlayer data class
- SessionHostHeartbeatInfo getters/setters and JSON deserialization
- SessionConfig including ToMapAllStrings
- Operation enum Gson serialization with @SerializedName casings
- MaintenanceSchedule/MaintenanceEvent deserialization
- JsonFileConfiguration config file parsing and validation
- GameHostHealth/SessionHostStatus enum values
- GameserverSDK public API constant keys

Add .github/workflows/java-tests.yml CI workflow to run tests on PRs.

Co-authored-by: dgkanatsios <8256138+dgkanatsios@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dgkanatsios <8256138+dgkanatsios@users.noreply.github.com>
@dgkanatsios dgkanatsios force-pushed the copilot/add-unit-tests-gsdk branch from 97b0ef1 to 4fae61a Compare March 19, 2026 17:28
@dgkanatsios dgkanatsios requested a review from Copilot April 28, 2026 00:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds standalone (non-Unreal) C++ unit tests for the Unreal GSDK JSON contracts and wires them into CI, plus updates Unreal plugin documentation to clarify which files are required for integration.

Changes:

  • Introduces standalone GoogleTest-based C++ tests under UnrealPlugin/Tests (CMake + FetchContent + nlohmann/json).
  • Adds a GitHub Actions workflow to build/run those tests on PRs that touch UnrealPlugin/**.
  • Updates Unreal plugin docs to explicitly list which plugin files/folders should be copied into a game project.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
UnrealPlugin/ThirdPersonMPGSDKSetup.md Clarifies which UnrealPlugin artifacts to copy into Plugins/PlayFabGSDK.
UnrealPlugin/Tests/GSDKHeartbeatTests.cpp Adds standalone tests for heartbeat request/response JSON and operation handling.
UnrealPlugin/Tests/GSDKConfigTests.cpp Adds standalone tests for JSON config parsing/round-tripping.
UnrealPlugin/Tests/CMakeLists.txt CMake project for building/running the standalone Unreal GSDK tests.
UnrealPlugin/README.md Adds “Plugin files” section describing minimal files needed for integration.
.github/workflows/unreal-tests.yml New CI workflow to configure/build/ctest the standalone Unreal tests on PRs.

Comment on lines +247 to +252
// Parse heartbeat interval
if (j.contains("nextHeartbeatIntervalMs"))
{
result.nextHeartbeatIntervalMs = j["nextHeartbeatIntervalMs"].get<int>();
}

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DecodeHeartbeatResponse only copies nextHeartbeatIntervalMs from JSON and returns it as-is. In the real Unreal implementation (FGSDKInternal::DecodeHeartbeatResponse), the interval is clamped to the configured minimum and defaults to the minimum when the field is missing. Consider modeling that behavior in this helper (e.g., pass/define a minimum interval and apply the clamp/default) so the standalone tests assert the same semantics as the plugin code.

Copilot uses AI. Check for mistakes.
Comment on lines +615 to +622
TEST_F(HeartbeatResponseTest, MissingHeartbeatIntervalDefaultsToZero)
{
std::string responseJson = R"({
"operation":"Continue"
})";

auto response = DecodeHeartbeatResponse(responseJson);
EXPECT_EQ(response.nextHeartbeatIntervalMs, 0);

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test asserts that a missing nextHeartbeatIntervalMs defaults to 0, but the Unreal GSDK sets NextHeartbeatIntervalMs to MinimumHeartbeatInterval when the field is absent. Updating the test expectation (and/or the standalone decode helper) to match the plugin behavior will prevent documenting an incorrect contract.

Suggested change
TEST_F(HeartbeatResponseTest, MissingHeartbeatIntervalDefaultsToZero)
{
std::string responseJson = R"({
"operation":"Continue"
})";
auto response = DecodeHeartbeatResponse(responseJson);
EXPECT_EQ(response.nextHeartbeatIntervalMs, 0);
TEST_F(HeartbeatResponseTest, MissingHeartbeatIntervalDefaultsToMinimum)
{
// Matches FConfigurationBase::GetMinimumHeartbeatInterval
const int minimumHeartbeatInterval = 1000;
std::string responseJson = R"({
"operation":"Continue"
})";
auto response = DecodeHeartbeatResponse(responseJson);
EXPECT_EQ(response.nextHeartbeatIntervalMs, minimumHeartbeatInterval);

Copilot uses AI. Check for mistakes.
Comment on lines +181 to +188
static constexpr const char* TEST_DIR = "/tmp/gsdk_config_tests";
std::string configFilePath;

void SetUp() override
{
std::filesystem::create_directories(TEST_DIR);
configFilePath = std::string(TEST_DIR) + "/testConfig.json";
}

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests write to a fixed /tmp/gsdk_config_tests/testConfig.json path. This is not portable (e.g., Windows) and can cause collisions if tests are run in parallel. Prefer using std::filesystem::temp_directory_path() plus a unique subdirectory/filename (e.g., std::filesystem::unique_path) and clean it up in TearDown().

Copilot uses AI. Check for mistakes.
Comment on lines +200 to +206
std::ofstream file(configFilePath);
file << config.dump(4);
}

json ReadConfigFromFile()
{
std::ifstream file(configFilePath);

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WriteConfigToFile and ReadConfigFromFile don't verify that the file streams opened successfully before writing/parsing. Adding assertions (e.g., ASSERT_TRUE(file.is_open())) will make failures much easier to diagnose if the temp path is not writable or the file can't be created.

Suggested change
std::ofstream file(configFilePath);
file << config.dump(4);
}
json ReadConfigFromFile()
{
std::ifstream file(configFilePath);
std::ofstream file(configFilePath);
ASSERT_TRUE(file.is_open()) << "Failed to open config file for writing: " << configFilePath;
file << config.dump(4);
}
json ReadConfigFromFile()
{
std::ifstream file(configFilePath);
EXPECT_TRUE(file.is_open()) << "Failed to open config file for reading: " << configFilePath;
if (!file.is_open())
{
return json();
}

Copilot uses AI. Check for mistakes.
@dgkanatsios dgkanatsios deleted the copilot/add-unit-tests-gsdk branch April 28, 2026 01:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants