PaulStoffregen / OneWire

Library for Dallas/Maxim 1-Wire Chips
http://www.pjrc.com/teensy/td_libs_OneWire.html
579 stars 382 forks source link

Basic unit testing of OneWire using TravisCI + arduino_ci #67

Open ianfixes opened 5 years ago

ianfixes commented 5 years ago

Relating to discussion in https://github.com/arduino/Arduino/issues/7567 , I've added CI capability + some unit tests to this repository using Travis CI and arduino_ci. I'm not an expert on the OneWire protocol itself, so the contributions will seem rather ignorant -- not least because I simply made the "actual behavior" into the "expected behavior" for the following functions:

The CI will execute those unit tests, as well as compilation tests of all examples, on the platforms defined in .arduino-ci.yaml (currently just due; I wasn't sure which platforms are relevant).

Of course, Travis needs to be enabled for this repository first. You can test it locally (as I did) with a ruby 2.0 environment, by running the following:

$ bundle install
$ bundle exec arduino_ci_remote.rb

Enabling Travis

This is the place where the automated tests will be: https://travis-ci.org/PaulStoffregen/OneWire

 Login Use your GitHub login to register for Travis. This is required -- | --  Travis Settings  | Once logged in, you can Sync your account and Search for the repository you want to automate

(via)

This was a fun exercise -- the OneWire library helped me unearth a few compilation errors and other shortcomings in my test library.

ianfixes commented 5 years ago

@PaulStoffregen now that https://github.com/ianfixes/arduino_ci/issues/23 is fixed, I've updated this PR to include actual tests of the OneWire timing:

#define PIN 10

unittest(signal_timing) {
  GodmodeState* state = GODMODE();
  state->reset();
  OneWire ow(PIN);
  ow.write(0xAC, 0);   // our test data: 1010 1100

  unsigned long timing[18]; // to store event timestamps: initial value, 8 pairs, final low
  state->digitalPin[PIN].toTimestampArray(timing, 18);  // fill the timing array with the microseconds values

  // verify transmitted data, apparently it goes out little-endian
  // 0xAC -> 10101100 becomes 00110101
  // 
  // the indices are all odd numbers because each transmitted bit is 2 digitalWrites
  // and the history given to toTimestampArray has an initial LOW that we skip over.
  assertEqual(0, delayToBit(timing, 1));
  assertEqual(0, delayToBit(timing, 3));
  assertEqual(1, delayToBit(timing, 5));
  assertEqual(1, delayToBit(timing, 7));
  assertEqual(0, delayToBit(timing, 9));
  assertEqual(1, delayToBit(timing, 11));
  assertEqual(0, delayToBit(timing, 13));
  assertEqual(1, delayToBit(timing, 15));
}

Where delayToBit is defined as follows:

// look at the difference between 2 consecutive values in a timestamp array
// and interpret the pulse duration as indicating 1, 0, or indeterminate (-1)
// (according to 1-Wire protocol)
int delayToBit(unsigned long* timestamps, int lowIndex) {
  int duration = timestamps[lowIndex + 1] - timestamps[lowIndex];
  if (duration <= 15) return 1;
  if (duration >= 60) return 0;
  return -1; // indicating error
}

What are your thoughts on the usefulness of this? Are there other features you'd like to ensure can be tested?