Hotwheels-Cluster 1.2
Creation of Cluster APP for SEA:ME project.
 
Loading...
Searching...
No Matches
test_MCP2515Controller.cpp
Go to the documentation of this file.
1
14
15#include "MCP2515Controller.hpp"
16#include "MockSPIController.hpp"
17#include <QObject>
18#include <QSignalSpy>
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21#include <thread>
22
23using ::testing::_;
24using ::testing::Return;
25using ::testing::Throw;
26
45
53TEST_F(MCP2515ControllerTest, InitializationSuccess) {
54 EXPECT_CALL(mockSPI, openDevice("/dev/spidev0.0")).WillOnce(Return(true));
55 EXPECT_CALL(mockSPI, closeDevice()).Times(1);
56 EXPECT_CALL(mockSPI, spiTransfer(_, nullptr, 1)).WillOnce(Return());
57 EXPECT_CALL(mockSPI, readByte(_)).WillOnce(Return(0x80)).WillRepeatedly(Return(0x00));
58 EXPECT_CALL(mockSPI, writeByte(_, _)).Times(::testing::AtLeast(1));
59
60 MCP2515Controller controller("/dev/spidev0.0", mockSPI);
61 ASSERT_NO_THROW(controller.init());
62}
63
71TEST_F(MCP2515ControllerTest, InitializationFailure) {
72 EXPECT_CALL(mockSPI, openDevice("/dev/nonexistent")).WillOnce(Return(false));
73 ASSERT_THROW(MCP2515Controller("/dev/nonexistent", mockSPI),
74 std::runtime_error);
75}
76
84TEST_F(MCP2515ControllerTest, SetupHandlersTest) {
85 EXPECT_CALL(mockSPI, openDevice("/dev/spidev0.0")).WillOnce(Return(true));
86 EXPECT_CALL(mockSPI, closeDevice()).Times(1);
87 MCP2515Controller controller("/dev/spidev0.0", mockSPI);
88 auto &processor = controller.getMessageProcessor();
89
90 ASSERT_NO_THROW(
91 processor.registerHandler(0x100, [](const std::vector<uint8_t> &) {}));
92 ASSERT_NO_THROW(
93 processor.registerHandler(0x200, [](const std::vector<uint8_t> &) {}));
94}
95
103TEST_F(MCP2515ControllerTest, SpeedUpdatedSignal) {
104 EXPECT_CALL(mockSPI, openDevice("/dev/spidev0.0")).WillOnce(Return(true));
105 EXPECT_CALL(mockSPI, closeDevice()).Times(1);
106 MCP2515Controller controller("/dev/spidev0.0", mockSPI);
107
108 QSignalSpy speedSpy(&controller, &MCP2515Controller::speedUpdated);
109 auto &processor = controller.getMessageProcessor();
110
111 std::vector<uint8_t> data = {0x00, 0x00, 0x20, 0x41}; // Float value: 10.0
112 processor.processMessage(0x100, data);
113
114 ASSERT_EQ(speedSpy.count(), 1);
115 QList<QVariant> arguments = speedSpy.takeFirst();
116 ASSERT_EQ(arguments.at(0).toFloat(), 1.0F); // Speed divided by 10
117}
118
126TEST_F(MCP2515ControllerTest, RpmUpdatedSignal) {
127 EXPECT_CALL(mockSPI, openDevice("/dev/spidev0.0")).WillOnce(Return(true));
128 EXPECT_CALL(mockSPI, closeDevice()).Times(1);
129 MCP2515Controller controller("/dev/spidev0.0", mockSPI);
130
131 QSignalSpy rpmSpy(&controller, &MCP2515Controller::rpmUpdated);
132 auto &processor = controller.getMessageProcessor();
133
134 std::vector<uint8_t> data = {0x03, 0xE8}; // Integer value: 1000 RPM
135 processor.processMessage(0x200, data);
136
137 ASSERT_EQ(rpmSpy.count(), 1);
138 QList<QVariant> arguments = rpmSpy.takeFirst();
139 ASSERT_EQ(arguments.at(0).toInt(), 1000);
140}
141
149TEST_F(MCP2515ControllerTest, ProcessReadingCallsHandlers) {
150 EXPECT_CALL(mockSPI, openDevice("/dev/spidev0.0")).WillOnce(Return(true));
151 EXPECT_CALL(mockSPI, closeDevice()).Times(1);
152 EXPECT_CALL(mockSPI, readByte(_))
153 .WillOnce(Return(0x01)) // Indicate data available
154 .WillRepeatedly(Return(0x00)); // No more data
155 EXPECT_CALL(mockSPI, spiTransfer(_, _, _))
156 .WillRepeatedly([](const uint8_t *tx, uint8_t *rx, size_t length) {
157 if (length == 3 && tx[0] == 0x03) { // Read command
158 rx[1] = 0x12; // Frame ID part 1
159 rx[2] = 0x34; // Frame ID part 2
160 }
161 });
162 EXPECT_CALL(mockSPI, writeByte(_, _)).Times(::testing::AtLeast(1));
163
164 MCP2515Controller controller("/dev/spidev0.0", mockSPI);
165
166 std::thread readerThread([&controller]() { controller.processReading(); });
167
168 std::this_thread::sleep_for(std::chrono::milliseconds(50));
169 controller.stopReading();
170
171 readerThread.join();
172
173 ASSERT_TRUE(controller.isStopReadingFlagSet());
174}
175
182TEST_F(MCP2515ControllerTest, StopReadingStopsProcessing) {
183 EXPECT_CALL(mockSPI, openDevice("/dev/spidev0.0")).WillOnce(Return(true));
184 EXPECT_CALL(mockSPI, closeDevice()).Times(1);
185
186 MCP2515Controller controller("/dev/spidev0.0", mockSPI);
187 controller.stopReading();
188 ASSERT_TRUE(controller.isStopReadingFlagSet());
189}
Definition of the MCP2515Controller class.
File containing Mock classes to test the SPI controller.
Class that processes CAN messages.
void processMessage(uint16_t frameID, const std::vector< uint8_t > &data)
Process a CAN message.
void rpmUpdated(int newRpm)
Signal emitted when the RPM is updated.
void speedUpdated(float newSpeed)
Signal emitted when the speed is updated.
Class that configures the MCP2515 CAN controller.
Test fixture for testing the MCP2515Controller class.
MCP2515Configurator configurator
MCP2515Configurator object.
MockSPIController mockSPI
Mocked SPI controller.
CANMessageProcessor messageProcessor
CANMessageProcessor object.
MCP2515ControllerTest()=default
MCP2515Controller object set as default.
Class that controls the MCP2515 CAN controller. IMCP2515Controller.
bool isStopReadingFlagSet() const override
Check if the stop reading flag is set.
void processReading() override
Start reading CAN messages.
bool init() override
Initialize the MCP2515 controller.
void stopReading() override
Stop reading CAN messages.
CANMessageProcessor & getMessageProcessor()
Class to emulate the behavior of the SPI controller. (Overrided the Can0)
TEST_F(MCP2515ControllerTest, InitializationSuccess)
Ensures that init() does not throw an exception.