serialport / node-serialport

Access serial ports with JavaScript. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them!
https://serialport.io
MIT License
5.82k stars 1.01k forks source link

Tooling: Run full test suite with loopback serial device #2327

Open cinderblock opened 3 years ago

cinderblock commented 3 years ago

💥 Proposal

The CI testing should try to test against a "plugged in" serial port.

Motivation

Some tests require talking to some "real" hardware. As discussed briefly in #2314, it would be nice if this was handled by the CI.

This issue is intended to track the discussion about certain options before committing to a particular path or starting a PR.

Pitch

Option 1: Virtual Serial Port

There are a number of virtual serial port emulation softwares available for install. Notably:

I personally think these options would be prefered since they could run directly on GH Action Runners

Option 2: Custom Runner Server

Maintain some dedicated hardware running a self-hosted runner and link it to this GH project. Someone would need to keep that hardware powered, running, and up to date. Doing this for 3 platforms seems possibly prohibitive.

Arduino vs Wire

If running on self-hosted hardware, is there some reason to not just run a wire from Rx to Tx? Why is there even an Arduino in the loop?

What about RTS/CTS/DTR/DTS signals?


Work in Progress

reconbot commented 3 years ago

A loop back is fine, once upon a time we had a more sophisticated arduino program that would change baud rates and mess with signals.

However I've never seen a virtual serialport without quirks. I tried pretty hard (pre GitHub actions) to get a reliable test env with a virtual port and failed. I'm 💯 in favor of us trying again.

Custom runners for open source projects are an ops challenge as the runner doesn't provide any sandboxing.

cinderblock commented 2 years ago

I've been working on this a little for the holidays.

I've got loopback devices for Linux and macOS partially working, using socat. When I test them manually, they seem to work. However there are some problems with setting ioctl options early in the node-serialport tests that prevent any subsequent tests from working.

Windows tools for virtual serial ports are a little lacking. com0com seems like it might be what we want but it doesn't directly support a loopback device. I'm investigating if com2tcp would be a workable alternative if used similar to how socat is used (using cat to echo back).

If anyone would like to follow along, I'm working over in my ci-loopback-serialport branch, but the good stuff is in the Actions.

reconbot commented 2 years ago

Very cool

cinderblock commented 2 years ago

@reconbot I have some questions you can probably shed some light on

What generates the bytes that the #read tests use?

I see that the Arduino test code echoes "READY", which the first read test needs, but what about the others?

I'm not seeing where in the tests (yet?) you expect the loopback functionality of the Arduino code to be used. It looks to me like every time the port is .open(), the Arduino resets, and re-runs it's setup() within a second and the tests pass from that. This might be an easier thing to test than a full loopback device...

The loopback devices I'm setting up now do not echo "READY" at startup. I'm currently hacking around this by making the tests .write('READY') after every open().

One crazy idea I'm considering is a simple C/C++ (or Go? That'd be fun to learn) program that creates a loopback serialport as I'm not particularly happy with the current socat solution. This would allow adding a "READY" echo, possibly on every open(). I think doing this on Windows wouldn't be that terrible either because com0com is fully open source. Would just be stripping a bunch of unnecessary features and adding a couple loopbacks.


End of weekend update

Tests are almost fully passing on Linux. MacOS is giving me some trouble. Not much progress on getting Windows's loopback COM port working.

cinderblock commented 2 years ago

Many tests are passing on Linux and macOS. Most issues are related to sending "READY" after DTR (open), which the Arduino does, but doesn't work in CI yet.

I can get some tests to "pass" by disabling certain tests with test-config.json, but these should be investigated more.

Windows is giving more trouble. Chocolatey's version of com0com isn't signed and doesn't work in the action runner. While you can download a signed version from sourceforge, I'm getting CERT_E_WRONG_USAGE errors when trying to load those, on my machine or CI.

I've also given Virtual Serial Port Driver a try, to no avail.


Helpful links relating to driver signing: