TESTING EMBEDDED SYSTEMS Itamar Hassin Fosdem 2016 @itababy - - PowerPoint PPT Presentation

testing embedded systems
SMART_READER_LITE
LIVE PREVIEW

TESTING EMBEDDED SYSTEMS Itamar Hassin Fosdem 2016 @itababy - - PowerPoint PPT Presentation

TESTING EMBEDDED SYSTEMS Itamar Hassin Fosdem 2016 @itababy SUBJECTS COVERED Unit testing (Unity) BDD (Cucumber) as a front-end for functional & acceptance tests Orchestrating tests across multiple targets CHALLENGES


slide-1
SLIDE 1

TESTING
 EMBEDDED SYSTEMS

Itamar Hassin Fosdem 2016 @itababy

slide-2
SLIDE 2

SUBJECTS COVERED

  • Unit testing (Unity)
  • BDD (Cucumber) as a front-end for functional &

acceptance tests

  • Orchestrating tests across multiple targets
slide-3
SLIDE 3

CHALLENGES TESTING EMBEDDED SOFTWARE

Hope that it cross-compiles Hope that it runs on
 hardware Optimal

Write simulator Run tests on simulator Develop hardware Run tests on hardware Run tests locally

slide-4
SLIDE 4

SOLID TESTING

slide-5
SLIDE 5

UNITY TEST CODE

void test_1(void)
 {
 TEST_ASSERT_EQUAL(2+2, 4);
 }
 
 void test_2(void)
 {
 TEST_ASSERT_EQUAL(1+1, 3);
 }

slide-6
SLIDE 6

UNITY RUNNER CODE

int main(void) { SetupTests(); RUN_TEST(test_1); RUN_TEST(test_2); TeardownTests(); }

slide-7
SLIDE 7

BUILD UNIT TESTS

slide-8
SLIDE 8

FLASH UNIT TESTS

slide-9
SLIDE 9

SEE IT RUN

slide-10
SLIDE 10

BDD FOR EMBEDDED

slide-11
SLIDE 11

THE CASE FOR BDD

  • Describes the behaviour in simple English
  • Promotes collaboration within the product team
  • Highlights business value
  • Direct mapping from user story acceptance

criteria

  • Living documentation, unified view of the product
slide-12
SLIDE 12

COLLABORATION

Feature: Patient monitoring
 
 Scenario: Alert nurse on disconnect
 Given patient is monitored
 When I disconnect the monitor
 Then I am alerted

slide-13
SLIDE 13

IMPLEMENT A SIMULATOR

class Monitor def disconnect driver.led(RED, ON) end end

slide-14
SLIDE 14

IMPLEMENT FEATURE STEP

Given(/^patient is monitored$/) do pending end When(/^I disconnect the monitor $/) do monitor.disconnect end

slide-15
SLIDE 15

VALIDATE UNDER SIMULATOR

Feature: Patient monitoring
 
 Scenario: Alert nurse on disconnect
 Given patient is monitored
 When I disconnect the monitor
 Then I am alerted … 1 scenarios (1 passed) 3 steps (3 passed) 0m0.0052s

slide-16
SLIDE 16

WHEN SIMULATION IS NOT ENOUGH

slide-17
SLIDE 17

IN-SITU TESTING

TCP? BLE?

slide-18
SLIDE 18

THE “WIRE”

  • When your system does not have native support
  • When you want a lean, portable implementation
slide-19
SLIDE 19

SIMPLIFIED WIRE PROTOCOL

slide-20
SLIDE 20

WIRE IMPLEMENTATION BLUEPRINT

  • TCP/IP loop managing Cucumber protocol
  • Function table for API invocation
  • API proxy implementation returning status to

Cucumber

slide-21
SLIDE 21

HOST HOOKING CUCUMBER TO WIRE SERVER

features/step_definitions/cucumber.wire host: host
 port: 3901

Redirect

slide-22
SLIDE 22

SERVER TCP/IP LOOP

while(1)
 {
 getRequest(…);
 handleRequest(…);
 }

Listen

slide-23
SLIDE 23

BRIDGE TO DEVICE

int begin_callback(…)
 {
 serial_open(…);
 }
 
 int end_callback(…)
 {
 serial_close(…);
 }

Bridge

slide-24
SLIDE 24

UP CLOSE AND PERSONAL

slide-25
SLIDE 25

WIRE SERVER TO THE DEVICE

int patient_is_monitored(…)
 {
 serial_write(…,"EXEC 0\r");
 serial_read(…);
 return(retVal);
 }

slide-26
SLIDE 26

DEVICE RPC SERVER LOOP

while (true)
 {
 chr = uart_read_byte();
 handle(command_buffer);
 }

Listen

slide-27
SLIDE 27

DEVICE API IMPLEMENTATION

if(strstr(command, “1")) { nrf_gpio_pin_clear(GREEN);
 nrf_gpio_pin_set(RED);
 return("0\n");
 }

slide-28
SLIDE 28

WIRE SERVER BACK TO CUCUMBER

if(retVal == 0)
 {
 strcpy(buffer, "[\"success\"]\n");
 } else {
 sprintf(buffer, “[\”fail\", …); }

slide-29
SLIDE 29

RUNNING THE TEST

slide-30
SLIDE 30

SEE IT RUN

slide-31
SLIDE 31

REAL APPS NEED THREADS

RPC Loop Thread Queue App thread Queue Implementation

slide-32
SLIDE 32

IMPLEMENTATION STACK

slide-33
SLIDE 33

WORKING WITH CUCUMBER

  • Decide on a strategy (off-board, on-board)
  • Get appropriate toolchain (cross compiler, linker)
  • Implement and port Wire to target
  • Run the feature files
  • fail/implement/pass/refactor/repeat
slide-34
SLIDE 34

SCRIPTING THE DEVICE

Wire Server

TCP/IP

RPC Server

Given When Then

Device APIs

Thread Thread

slide-35
SLIDE 35

COMPLEX ENVIRONMENT

slide-36
SLIDE 36

GATEWAY

  • Acts as an end-to-end test orchestrator
  • Switchboard events across heterogeneous devices
slide-37
SLIDE 37

COLLABORATIVE END-TO-END TESTING

Framework running on PC C-implementation Cucumber- Wire running

  • n Target

Targets Native Wire Collaboration

slide-38
SLIDE 38

GATEWAY ARCHITECTURE

SpecFlow Target B Proxies A1 B1 Hardware Serial Wire Target A Cucumber Behave

slide-39
SLIDE 39

END-TO-END FEATURES

Feature: Alarm assured to appear in quiet mode Scenario: Pressure alarm Given device is in quiet mode When pressure sensor is disconnected Then a silent alarm will appear

slide-40
SLIDE 40

GATEWAY STEPS

public class QuietModeSteps { SignalSimulator signalSimulator = new SignalSimulator(); MedicalDevice medicalDevice = new MedicalDevice(“192.168.1.1”, 3901); [Given(@"device is quiet mode")] public void GivenDeviceIsQuietMode() { Assert.IsTrue(medicalDevice.SetQuietMode()); } [When(@“pressure sensor is disconnected")] public void GivenPressureSensorIsDisconnected() { Assert.IsTrue(signalSimulator.SetPressure(off)); } }

Serial Wire

  • n device
slide-41
SLIDE 41

GATEWAY PROXIES

class MedicalDevice { public MedicalDevice(string ipAddress, int port) { wire = new Wire(myAddress, port); wire.Open(); } public bool SetQuietMode() { wire.Send(“[\"step_matches\", {\"name_to_match\":\"set quiet mode on\"}]\n"); wire.Send("[\"invoke\",{\"id\":\"7\",\"args\":[\"on\"]}]\n"); return(wire.Ack()); } }

Ugh…

slide-42
SLIDE 42

EMULATING WIRE

public class Wire { public int Open() { client = new TcpClient(myAddress, myPort); stream = client.GetStream(); return(Send(“[\”begin_scenario\"]\n")); } public int Close() { stream = client.GetStream(); Send("[\"end_scenario\"]\n"); return(client.Close()); } }

slide-43
SLIDE 43

SpecFlow Wire Proxies A1 Target

TCP Given … quiet mode

Wire

int SetQuietMode(“on”) {} Match: “set quiet\’(on|off)’\” Invoke: idx:0, params: “on”

SPECFLOW TO WIRE

int set_quiet(char* state){}

A

slide-44
SLIDE 44
  • Security - Anyone can connect to Wire!
  • Regulation may not allow non-application code on

a production system Shut down the wire thread in production

COMPLIANCE CONSIDERATIONS

slide-45
SLIDE 45

LESSONS LEARNED

Threading Vocabulary Threads & Target Architecture

slide-46
SLIDE 46

OPEN SOURCE

  • Unit testing example

https://github.com/ihassin/nrf51-unity

  • Cucumber/Listener/RPC example

https://github.com/ihassin/cucumber-wire-tcp2serial

  • Development environment provisioning (Linux)

https://github.com/ihassin/fruitymesh-ubuntu-vm

  • Development environment provisioning (OS-X)

https://github.com/ihassin/fruitymesh-mac-osx

slide-47
SLIDE 47

REFERENCES

  • Specification by example
  • The Cucumber Book
  • Cucumber Recipes

@history_pics/@historyinpics Jim Reese#Wikipedia National Library of Australia Photo Credits:

  • SpecFlow
  • Nordic Semiconductor
  • Unity
  • Cucumber
slide-48
SLIDE 48

THANK YOU!

@itababy www.in-context.com