Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DCCEXProtocol cross platform #14

Merged
merged 4 commits into from
Feb 25, 2024
Merged

Make DCCEXProtocol cross platform #14

merged 4 commits into from
Feb 25, 2024

Conversation

higaski
Copy link
Contributor

@higaski higaski commented Jan 18, 2024

This PR introduces rudimentary CMake support for non-Arduino targets. The CMakeLists.txt file creates a static library target called DCCEXProtocol (aliased as DCCEX::Protocol).

To get this to work the hardware independent ArduinoCore-API gets included as dependency. I've removed direct dependencies to the <Arduino.h> header (which isn't available in the Core-API) in all files and instead included the necessary interfaces (e.g. Stream.h, Print.h, ...).

The ArduinoCore-API has no CMake support so a Find<PackageName>.cmake file had to be written. A common convention is to place such files in a cmake subfolder.

With those changes in place the DCCEXProtocol library can be compiled on any platform.

@github-actions github-actions bot added the DCCEXProtocol Item relates to the DCCEXProtocol Arduino library specifically label Jan 18, 2024
@higaski higaski marked this pull request as draft January 29, 2024 19:23
@higaski higaski marked this pull request as ready for review January 31, 2024 12:44
@higaski
Copy link
Contributor Author

higaski commented Jan 31, 2024

As discussion on discord this PR got extended with

  • clang-format integration
  • Unit test integration using GTest
  • GitHub action running the tests

clang-format integration

I've added a .clang-format file. So far this file formats to the basic LLVM style. Feel free to modify it to your liking. I have not run the formatter on the code inside /src.

Unit test integration

I've added a /tests subfolder containing three very small "best case" tests. Best case as in I haven't tried anything malicious yet. 😈

I've written a simple test fixture for the DCCEXProtocol class

class DCCEXProtocolTest : public Test {
public:
  DCCEXProtocolTest();
  virtual ~DCCEXProtocolTest();

protected:
  DCCEXProtocol _dccexProtocol;
  DCCEXProtocolDelegateMock _delegate;
  StreamMock _stream;
};

This class contains an instance of DCCEXProtocol, a StreamMock which allows some test input and a DCCEXProtocolDelegateMock which can be used to verify that the command responses get parsed correctly.

Lets look at the allTracksOff test case for example. In case the character sequence <p0> is received the method receivedTrackPower from our delegate is expected to get called.

TEST_F(DCCEXProtocolTest, allTracksOff) {
  _stream << "<p0>";
  EXPECT_CALL(_delegate, receivedTrackPower(TrackPower::PowerOff))
      .Times(Exactly(1));
  _dccexProtocol.check();
}

So far so good. I also wanted to enable sanitizers to detect certain memory bugs. This made me realize that the string handling code needs work. There are numerous memory leaks because the code allocates multiple times but never frees memory. The address sanitizer further more detected a heap buffer overflow inside _nextServerDescriptionParam.

For the sake of this PR I've not default enabled sanitizers yet. To do so one must pass -DSANITIZE=ON to the CMake invocation.

GitHub action

Finally I've added a GitHub action called tests which runs all tests on every push of main or every PR to main. Again, as with the .clang-format file, please feel free to modify the action to whatever suits your needs.

@higaski
Copy link
Contributor Author

higaski commented Feb 1, 2024

I've deleted the commit which changed the included header files. The necessary Arduino.h header for non Arduino platforms is now written by CMake.

# Create Arduino.h header
file(
  WRITE ${arduinocore-api_BINARY_DIR}/Arduino.h #
  "#ifndef Arduino_h\n" #
  "#define Arduino_h\n" #
  "#include \"ArduinoAPI.h\"\n" #
  "#endif" #
)

@higaski
Copy link
Contributor Author

higaski commented Feb 19, 2024

An upstream problem prevents compilation on case insensitive operating systems.

Workaround for Windows:

  1. Open PowerShell as Administrator and run
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  2. Reboot
  3. Switch to your development folder, open PowerShell and run
    (Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}
    to recursively enable case sensitivity for all subdirs

@peteGSX peteGSX merged commit 4b5681a into DCC-EX:main Feb 25, 2024
2 checks passed
@higaski higaski mentioned this pull request Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DCCEXProtocol Item relates to the DCCEXProtocol Arduino library specifically
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants