Skip to content
Closed
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: 3 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ on:
workflow_dispatch:
push:
branches: [ master, github-workflow-playground ]
pull_request:
branches: [ master ]
schedule:
- cron: "0 0 * * *"

Expand Down Expand Up @@ -423,6 +421,9 @@ jobs:
- name: Test
run: cd tst; GTEST_OUTPUT=xml:test-results/ GTEST_COLOR=1 ./qdomyos-zwift-tests; cd ..

- name: Test DirCon loopback integration
run: cd tst; GTEST_OUTPUT=xml:test-results/dircon-loopback.xml GTEST_COLOR=1 ./qdomyos-zwift-tests --gtest_filter=DirconLoopbackTestSuite.*; cd ..

- name: Upload test results
uses: actions/upload-artifact@v4
if: failure()
Expand Down
71 changes: 71 additions & 0 deletions tst/Devices/dirconloopbacktestsuite.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "dirconloopbacktestsuite.h"

#include <QCoreApplication>
#include <QDateTime>
#include <QEventLoop>
#include <QSettings>
#include <functional>

#include "Tools/testsettings.h"
#include "devices/dircon/dirconmanager.h"
#include "devices/dircon/wahoodirconbike.h"
#include "devices/fakebike/fakebike.h"
#include "qzsettings.h"

namespace {

bool waitForCondition(const std::function<bool()> &predicate, int timeoutMs) {
const QDateTime endTime = QDateTime::currentDateTime().addMSecs(timeoutMs);
while (QDateTime::currentDateTime() < endTime) {
if (predicate()) {
return true;
}
QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
}
return predicate();
}

} // namespace

void DirconLoopbackTestSuite::test_fakebike_dircon_server_accepts_wahoodirconbike_client() {
TestSettings testSettings(QStringLiteral("qz-test-org"), QStringLiteral("qz-test-dircon-loopback"));
testSettings.activate();

constexpr int kServerBasePort = 46000;
testSettings.qsettings.setValue(QZSettings::dircon_yes, true);
testSettings.qsettings.setValue(QZSettings::dircon_server_base_port, kServerBasePort);
testSettings.qsettings.setValue(QZSettings::dircon_id, 1);
testSettings.qsettings.setValue(QZSettings::virtual_device_enabled, false);
testSettings.qsettings.setValue(QZSettings::zwift_play_emulator, false);
testSettings.qsettings.setValue(QZSettings::rouvy_compatibility, false);

fakebike serverBike(true, true, true);
DirconManager dirconServer(&serverBike, 4, 1.0);

DirconDeviceInfo deviceInfo;
deviceInfo.name = QStringLiteral("Wahoo KICKR 0001");
deviceInfo.displayName = QStringLiteral("Wahoo KICKR 0001 (DirCon)");
deviceInfo.address = QStringLiteral("127.0.0.1");
deviceInfo.port = static_cast<quint16>(kServerBasePort);

wahoodirconbike clientBike(deviceInfo, true, true, 4, 1.0);

const bool connected = waitForCondition([&clientBike]() { return clientBike.connected(); }, 5000);
EXPECT_TRUE(connected) << "DirCon client failed to complete handshake against local fakebike DirCon server";

// Drive the fakebike with target power to force metric updates on the DirCon server side,
// then verify the client receives non-zero telemetry through notifications.
serverBike.changePower(180);

const bool receivedTelemetry = waitForCondition(
[&clientBike]() {
return clientBike.wattsMetric().value() > 0 &&
clientBike.currentCadence().value() > 0 &&
clientBike.currentSpeed().value() > 0;
},
8000);
EXPECT_TRUE(receivedTelemetry)
<< "DirCon client connected but did not receive expected bike telemetry (watt/cadence/speed)";

testSettings.deactivate();
}
15 changes: 15 additions & 0 deletions tst/Devices/dirconloopbacktestsuite.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef DIRCONLOOPBACKTESTSUITE_H
#define DIRCONLOOPBACKTESTSUITE_H

#include "gtest/gtest.h"

class DirconLoopbackTestSuite : public testing::Test {
public:
void test_fakebike_dircon_server_accepts_wahoodirconbike_client();
};

TEST_F(DirconLoopbackTestSuite, FakeBikeDirconServerAcceptsWahooDirconBikeClient) {
this->test_fakebike_dircon_server_accepts_wahoodirconbike_client();
}

#endif // DIRCONLOOPBACKTESTSUITE_H
2 changes: 2 additions & 0 deletions tst/qdomyos-zwift-tests.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SOURCES += \
Devices/bluetoothdevicetestsuite.cpp \
Devices/bluetoothsignalreceiver.cpp \
Devices/devicediscoveryinfo.cpp \
Devices/dirconloopbacktestsuite.cpp \
Devices/deviceindex.cpp \
Devices/devicenamepatterngroup.cpp \
Devices/devicetestdataindex.cpp \
Expand Down Expand Up @@ -50,6 +51,7 @@ HEADERS += \
Devices/bluetoothdevicetestsuite.h \
Devices/bluetoothsignalreceiver.h \
Devices/devicediscoveryinfo.h \
Devices/dirconloopbacktestsuite.h \
Devices/deviceindex.h \
Devices/devicenamepatterngroup.h \
Devices/devicetestdataindex.h \
Expand Down