Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jobs:
git config --global --add safe.directory /home/runner/work/megaglest-source/megaglest-source
cd mk/linux
./build-mg.sh -f
ctest --test-dir build --output-on-failure

build-linux:
strategy:
Expand Down Expand Up @@ -91,6 +92,10 @@ jobs:
mk/linux/build-mg.sh -m ${EXTRA_OPTS}
make -C mk/linux/build -j$(nproc) VERBOSE=1

- name: Run tests
if: ${{ matrix.release != true && matrix.compiler == 'gcc' }}
run: ctest --test-dir mk/linux/build --output-on-failure

- name: Build Release
if: ${{ matrix.release == true }}
run: |
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jobs:
mk/macos/build-mg.sh -m
make -C mk/macos/build -j$(sysctl -n hw.ncpu) VERBOSE=1

- name: Run tests
run: ctest --test-dir mk/macos/build --output-on-failure

- name: Git Hash
if: ${{ github.ref == 'refs/heads/develop' }}
run: |
Expand Down
27 changes: 27 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,33 @@ cd builddir
cmake -LH
```

## Unit tests

Unit tests are built by default (enabled by `-DBUILD_MEGAGLEST_TESTS=ON` in
`build-mg.sh`). After a successful build the test binary is at:

mk/linux/megaglest_tests # Linux
mk/macos/megaglest_tests # macOS

Run all tests via CTest:

ctest --test-dir mk/linux/build --output-on-failure

Or run the binary directly, optionally filtering by suite or test name:

./mk/linux/megaglest_tests
./mk/linux/megaglest_tests SocketTest
./mk/linux/megaglest_tests SocketTest::test_ip_ipv6_cursor_stripped

To run tests as part of the build script:

./mk/linux/build-mg.sh -t # build then run tests

Tests live under `source/tests/`. To add tests for a new subsystem, create a
subdirectory under `source/tests/shared_lib/` and add it to `DIRS_WITH_SRC` in
`source/tests/CMakeLists.txt` — the glob will pick up any `.cpp` files there
automatically.

## Installing from manual build

> [!CAUTION]
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ ENDIF()

PROJECT( MegaGlest )

enable_testing()

# This helps prevent certain errors such as what's mentioned in
# https://github.com/MegaGlest/megaglest-source/pull/300
# and also some consider it good practice to specify a standard
Expand Down
15 changes: 14 additions & 1 deletion mk/linux/build-mg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ LUA_FORCED_VERSION=0
FORCE_32BIT_CROSS_COMPILE=0
COMPILATION_WITHOUT=0
BUILD_MEGAGLEST_TESTS="ON"
RUN_TESTS=0
SHOW_CMAKE_OPTIONS=0

while getopts "B:c:defg:hl:mnopswx" option; do
while getopts "B:c:defg:hl:mnopswxt" option; do
case "${option}" in
B)
BUILD_DIR=${OPTARG}
Expand Down Expand Up @@ -72,6 +73,7 @@ while getopts "B:c:defg:hl:mnopswx" option; do
echo " -w : Force compilation 'Without using wxWidgets'"
echo " -x : Force cross compiling on x64 linux to produce an x86 32 bit binary"

echo " -t : Run unit tests after build (requires -DBUILD_MEGAGLEST_TESTS=ON)"
echo " -o : Show available cmake options"
echo " -h : Display this help usage"
echo " -- : Pass remaining arguments verbatim to cmake"
Expand Down Expand Up @@ -111,6 +113,9 @@ while getopts "B:c:defg:hl:mnopswx" option; do
FORCE_32BIT_CROSS_COMPILE=1
# echo "${option} value: ${OPTARG}"
;;
t)
RUN_TESTS=1
;;

\?)
echo "Script Invalid option: -$OPTARG" >&2
Expand Down Expand Up @@ -376,6 +381,14 @@ else
echo 'ERROR: MAKE failed.' >&2; exit 2
fi

if [ $RUN_TESTS = 1 ]; then
echo "==================> Running unit tests... <=================================="
ctest --output-on-failure
if [ $? -ne 0 ]; then
echo 'ERROR: Tests failed.' >&2; exit 3
fi
fi

cd ..
echo ''
echo 'BUILD COMPLETE.'
Expand Down
20 changes: 11 additions & 9 deletions mk/macos/build-mg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ WANT_STATIC_LIBS="-DWANT_STATIC_LIBS=ON"
FORCE_EMBEDDED_LIBS=0
LUA_FORCED_VERSION=0
COMPILATION_WITHOUT=0
RUN_TESTS=0
SHOW_CMAKE_OPTIONS=0

# Some brew things don't appear to link correctly by themselves.
Expand Down Expand Up @@ -54,7 +55,7 @@ then
fi
fi

while getopts "B:c:defhl:mnopwxb" option; do
while getopts "B:c:defhl:mnoptwxb" option; do
case "${option}" in
B) BUILD_DIR=${OPTARG};;
c) CPU_COUNT=${OPTARG};;
Expand All @@ -73,6 +74,7 @@ while getopts "B:c:defhl:mnopwxb" option; do
echo " -l x : Force using LUA version x - example: -l 5.3"
echo " -m : Force running CMAKE only to create Make files (do not compile)"
echo " -n : Force running MAKE only to compile (assume CMAKE already built make files)"
echo " -t : Run unit tests after build (requires -DBUILD_MEGAGLEST_TESTS=ON)"
echo " -w : Force compilation 'Without using wxWidgets'"
echo " -x : Force usage of Xcode and xcodebuild"
echo " -o : Show available cmake options"
Expand All @@ -90,6 +92,7 @@ while getopts "B:c:defhl:mnopwxb" option; do
fi
SHOW_CMAKE_OPTIONS=1
CMAKE_ONLY=1;;
t) RUN_TESTS=1;;
w) COMPILATION_WITHOUT=1;;
x) USE_XCODE=1;;
b) BUILD_BUNDLE=1
Expand Down Expand Up @@ -237,14 +240,7 @@ fi
if [ "$MAKE_ONLY" -eq "0" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DWANT_DEV_OUTPATH=ON $WANT_STATIC_LIBS -DBREAKPAD_ROOT=$BREAKPAD_ROOT"
if [ "$BUILD_BUNDLE" -ne "1" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DCMAKE_INSTALL_PREFIX=''"
if [ "$GCC_FORCED" -ne "1" ] || [ "$USE_XCODE" -eq "1" ]; then :
#^ Remove this condition when it V will start working on gcc
#EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DBUILD_MEGAGLEST_TESTS=ON"
#^ Uncomment when it will start working on clang
else
rm -f ../megaglest_tests
fi
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DCMAKE_INSTALL_PREFIX='' -DBUILD_MEGAGLEST_TESTS=ON"
rm -f ../MegaGlest*.dmg
else
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DCPACK_GENERATOR=Bundle -DWANT_SINGLE_INSTALL_DIRECTORY=ON"
Expand Down Expand Up @@ -276,6 +272,12 @@ else
echo "==================> About to call make with $NUMCORES cores... <=================="
make -j$NUMCORES
if [ "$?" -ne "0" ]; then echo 'ERROR: MAKE failed.' >&2; exit 2; fi

if [ "$RUN_TESTS" -eq "1" ]; then
echo "==================> Running unit tests... <=================================="
ctest --output-on-failure
if [ "$?" -ne "0" ]; then echo 'ERROR: Tests failed.' >&2; exit 3; fi
fi
fi

if [ -d "../Debug" ]; then mv -f ../Debug/megaglest* "$SCRIPTDIR"; rm -rf ../Debug
Expand Down
7 changes: 6 additions & 1 deletion mk/windoze/build-mg-vs-cmake.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Build MegaGlest on Windows.
# Author: James Sherratt.
param(${vcpkg-location}, ${buildtype}, [string[]]${cmake-options}, [switch]${show-options})
param(${vcpkg-location}, ${buildtype}, [string[]]${cmake-options}, [switch]${show-options}, [switch]${run-tests})

$sword = [char]::ConvertFromUtf32(0x2694)
Write-Output "=====$sword MegaGlest $sword====="
Expand Down Expand Up @@ -145,6 +145,11 @@ cmake --build "$buildFolder" --config $buildtype --target ALL_BUILD

if ($?) {
"Build succeeded. megaglest.exe, megaglest_editor.exe and megaglest_g3dviewer.exe can be found in mk/windoze/."
if (${run-tests}) {
Write-Title "Running unit tests"
ctest --test-dir "$buildFolder" --build-config $buildtype --output-on-failure
if (!$?) { "Tests failed."; Exit 3 }
}
}
else {
"Build failed. Please make sure you have installed VS C++ tools (2019 or 2022): https://visualstudio.microsoft.com/downloads ."
Expand Down
7 changes: 1 addition & 6 deletions source/glest_game/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5321,12 +5321,7 @@ int glestMain(int argc, char **argv) {
string autoConnectServer = paramPartTokens[1];

int port = config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
vector<string> paramPartTokens2;
Tokenize(autoConnectServer, paramPartTokens2, ":");
autoConnectServer = paramPartTokens2[0];
if (paramPartTokens2.size() >= 2 && paramPartTokens2[1].length() > 0) {
port = strToInt(paramPartTokens2[1]);
}
Ip::parseHostPort(autoConnectServer, port);

printf("Connecting to host [%s] using port: %d\n", autoConnectServer.c_str(), port);
if (autoConnectServer == "auto-connect") {
Expand Down
87 changes: 19 additions & 68 deletions source/glest_game/menu/menu_state_join_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void MenuStateJoinGame::CommonInit(bool connect, Ip serverIp, int portNumberOver
containerName = "JoinGame";
abortAutoFind = false;
autoConnectToServer = false;
serverPortOverride = portNumberOverride;
Lang &lang = Lang::getInstance();
Config &config = Config::getInstance();
NetworkManager &networkManager = NetworkManager::getInstance();
Expand Down Expand Up @@ -165,13 +166,7 @@ void MenuStateJoinGame::CommonInit(bool connect, Ip serverIp, int portNumberOver

string host = labelServerIp.getText();
int portNumber = config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
std::vector<std::string> hostPartsList;
Tokenize(host, hostPartsList, ":");
if (hostPartsList.size() > 1) {
host = hostPartsList[0];
replaceAll(hostPartsList[1], "_", "");
portNumber = strToInt(hostPartsList[1]);
}
Ip::parseHostPort(host, portNumber);

string port = " (" + intToStr(portNumber) + ")";
labelServerPort.setText(port);
Expand All @@ -187,34 +182,17 @@ void MenuStateJoinGame::CommonInit(bool connect, Ip serverIp, int portNumberOver
connected = false;
playerIndex = -1;

// server ip
// server ip — label stores only the address; port is tracked via serverPortOverride
if (connect == true) {
string hostIP = serverIp.getString();
if (portNumberOverride > 0) {
hostIP += ":" + intToStr(portNumberOverride);
}

labelServerIp.setText(hostIP + "_");

labelServerIp.setText(serverIp.getString() + "_");
autoConnectToServer = true;
} else {
string hostIP = config.getString("ServerIp");
if (portNumberOverride > 0) {
hostIP += ":" + intToStr(portNumberOverride);
}

labelServerIp.setText(hostIP + "_");
labelServerIp.setText(config.getString("ServerIp") + "_");
}

host = labelServerIp.getText();
portNumber = config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
hostPartsList.clear();
Tokenize(host, hostPartsList, ":");
if (hostPartsList.size() > 1) {
host = hostPartsList[0];
replaceAll(hostPartsList[1], "_", "");
portNumber = strToInt(hostPartsList[1]);
}
portNumber = serverPortOverride > 0 ? serverPortOverride : config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
Ip::parseHostPort(host, portNumber);

port = " (" + intToStr(portNumber) + ")";
labelServerPort.setText(port);
Expand Down Expand Up @@ -247,14 +225,8 @@ void MenuStateJoinGame::reloadUI() {
labelServerPortLabel.setText(lang.getString("ServerPort"));

string host = labelServerIp.getText();
int portNumber = config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
std::vector<std::string> hostPartsList;
Tokenize(host, hostPartsList, ":");
if (hostPartsList.size() > 1) {
host = hostPartsList[0];
replaceAll(hostPartsList[1], "_", "");
portNumber = strToInt(hostPartsList[1]);
}
int portNumber = serverPortOverride > 0 ? serverPortOverride : config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
Ip::parseHostPort(host, portNumber);

string port = " (" + intToStr(portNumber) + ")";
labelServerPort.setText(port);
Expand Down Expand Up @@ -370,14 +342,8 @@ void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton) {

string host = labelServerIp.getText();
Config &config = Config::getInstance();
int portNumber = config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
std::vector<std::string> hostPartsList;
Tokenize(host, hostPartsList, ":");
if (hostPartsList.size() > 1) {
host = hostPartsList[0];
replaceAll(hostPartsList[1], "_", "");
portNumber = strToInt(hostPartsList[1]);
}
int portNumber = serverPortOverride > 0 ? serverPortOverride : config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
Ip::parseHostPort(host, portNumber);

string port = " (" + intToStr(portNumber) + ")";
labelServerPort.setText(port);
Expand Down Expand Up @@ -585,16 +551,10 @@ void MenuStateJoinGame::update() {
labelInfo.setText(lang.getString("WaitingHost"));

string host = labelServerIp.getText();
std::vector<std::string> hostPartsList;
Tokenize(host, hostPartsList, ":");
if (hostPartsList.size() > 1) {
host = hostPartsList[0];
replaceAll(hostPartsList[1], "_", "");
}
string saveHost = Ip(host).getString();
if (hostPartsList.size() > 1) {
saveHost += ":" + hostPartsList[1];
}
Config &config = Config::getInstance();
int portNumber = serverPortOverride > 0 ? serverPortOverride : config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
Ip::parseHostPort(host, portNumber);
string saveHost = Ip::buildHostDisplay(Ip(host).getString(), portNumber);

servers.setString(clientInterface->getServerName(), saveHost);
}
Expand Down Expand Up @@ -753,16 +713,10 @@ bool MenuStateJoinGame::connectToServer() {

Config &config = Config::getInstance();
string host = labelServerIp.getText();
int port = config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
std::vector<std::string> hostPartsList;
Tokenize(host, hostPartsList, ":");
if (hostPartsList.size() > 1) {
host = hostPartsList[0];
replaceAll(hostPartsList[1], "_", "");
port = strToInt(hostPartsList[1]);
}
int port = serverPortOverride > 0 ? serverPortOverride : config.getInt("PortServer", intToStr(GameConstants::serverPort).c_str());
Ip::parseHostPort(host, port);
serverPortOverride = port;
Ip serverIp(host);

ClientInterface *clientInterface = NetworkManager::getInstance().getClientInterface();
clientInterface->connect(serverIp, port);

Expand All @@ -788,10 +742,7 @@ bool MenuStateJoinGame::connectToServer() {
}
}
if (clientInterface->isConnected() == true && clientInterface->getIntroDone() == true) {
string saveHost = Ip(host).getString();
if (hostPartsList.size() > 1) {
saveHost += ":" + hostPartsList[1];
}
string saveHost = Ip::buildHostDisplay(Ip(host).getString(), port);
servers.setString(clientInterface->getServerName(), saveHost);
servers.save(serversSavedFile);

Expand Down
1 change: 1 addition & 0 deletions source/glest_game/menu/menu_state_join_game.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class MenuStateJoinGame : public MenuState, public DiscoveredServersInterface {
string serversSavedFile;
bool abortAutoFind;
bool autoConnectToServer;
int serverPortOverride;

public:
MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool connect = false, Ip serverIp = Ip(), int portNumberOverride = -1);
Expand Down
Loading