Skip to content

Commit

Permalink
feat: add functionality for setting up CAN devices
Browse files Browse the repository at this point in the history
Adds the "candevice" package which provides functions for interacting
with CAN devices on the link layer. Allows for setting bitrate, setting device
up/down, and retrieving info and stats from the device.

Added integration tests for the candevice package, for testing against real hardware.
  • Loading branch information
Hashem Hashem authored and hashemmm96 committed Nov 18, 2022
1 parent 0278ae5 commit 8d419f8
Show file tree
Hide file tree
Showing 9 changed files with 676 additions and 11 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.idea
tools/*/*/
build/

# files generated during release
.generated-go-semantic-release-changelog.md
.semrel/
18 changes: 18 additions & 0 deletions .sage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,21 @@ func GenerateTestdata(ctx context.Context) error {
cmd.Dir = sg.FromGitRoot()
return cmd.Run()
}

func BuildIntegrationTests(ctx context.Context) error {
sg.Logger(ctx).Println("building integration test...")
testDir := sg.FromGitRoot("build", "tests")
if err := os.MkdirAll(testDir, 0o775); err != nil {
return err
}
return sg.Command(
ctx,
"go",
"test",
"-tags=integration",
"-c",
sg.FromGitRoot("pkg", "candevice"),
"-o",
filepath.Join(testDir, "candevice.test"),
).Run()
}
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ update-sage: $(go)
clean-sage:
@git clean -fdx .sage/tools .sage/bin .sage/build

.PHONY: build-integration-tests
build-integration-tests: $(sagefile)
@$(sagefile) BuildIntegrationTests

.PHONY: convco-check
convco-check: $(sagefile)
@$(sagefile) ConvcoCheck
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,21 @@ var auxMsg *etruckcan.Auxiliary
_ = auxMsg.UnmarshalFrame(frame)

```

Running integration tests
-------------------------

Building the tests:

```
$ make build-integration-tests
```

Built tests are placed in build/tests.

The candevice test requires access to physical HW, so run it using sudo. Example:

```
$ ./build/tests/candevice.test
> PASS
```
11 changes: 7 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/fatih/color v1.13.0
github.com/golang/mock v1.6.0
github.com/mdlayher/netlink v1.7.0
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041
go.uber.org/goleak v1.1.12
golang.org/x/net v0.0.0-20220923203811-8be639271d50
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
golang.org/x/net v0.2.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.2.0
golang.org/x/tools v0.1.10
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gotest.tools/v3 v3.4.0
Expand All @@ -19,9 +20,11 @@ require (
require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/google/go-cmp v0.5.5 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/josharian/native v1.0.0 // indirect
github.com/mattn/go-colorable v0.1.9 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mdlayher/socket v0.4.0 // indirect
github.com/shurcooL/go v0.0.0-20190704215121-7189cc372560 // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
Expand Down
21 changes: 14 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
Expand All @@ -19,6 +22,10 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mdlayher/netlink v1.7.0 h1:ZNGI4V7i1fJ94DPYtWhI/R85i/Q7ZxnuhUJQcJMoodI=
github.com/mdlayher/netlink v1.7.0/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shurcooL/go v0.0.0-20190704215121-7189cc372560 h1:SpaoQDTgpo2YZkvmr2mtgloFFfPTjtLMlZkQtNAPQik=
Expand Down Expand Up @@ -47,13 +54,13 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220923203811-8be639271d50 h1:vKyz8L3zkd+xrMeIaBsQ/MNVPVFSffdaU3ZyYlBGFnI=
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -64,8 +71,8 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
119 changes: 119 additions & 0 deletions pkg/candevice/device_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//go:build integration

package candevice

import (
"fmt"
"testing"
)

const (
bitrate125K = 125000
bitrate250K = 250000
)

func TestSetBitrate(t *testing.T) {
d, err := New("can0")
if err != nil {
t.Fatal("couldn't set up device:", err)
}
defer d.SetDown()

if err := setBitrate(d, bitrate125K); err != nil {
t.Fatal(err)
}
if err := setBitrate(d, bitrate250K); err != nil {
t.Fatal(err)
}

// Set bitrate on device which is up
if err := d.SetUp(); err != nil {
t.Fatal(err)
}
if err := setBitrate(d, bitrate125K); err == nil {
t.Fatal("setting bitrate on device which is up succeeded")
}
if err := d.SetDown(); err != nil {
t.Fatal(err)
}

// Invalid bitrate
if err := setBitrate(d, 0); err == nil {
t.Fatal("setting invalid bitrate succeeded")
}
}

func TestSetUpDown(t *testing.T) {
d, err := New("can0")
if err != nil {
t.Fatal("couldn't set up device:", err)
}
defer d.SetDown()

if err := d.SetBitrate(bitrate125K); err != nil {
t.Fatal(err)
}

// Set up twice and set down twice. This checks that calling it twice has no effect
if err := setUp(d); err != nil {
t.Fatal(err)
}
if err := setUp(d); err != nil {
t.Fatal(err)
}
if err := setDown(d); err != nil {
t.Fatal(err)
}
if err := setDown(d); err != nil {
t.Fatal(err)
}
}

func setBitrate(d *Device, bitrate uint32) error {
if err := d.SetBitrate(bitrate); err != nil {
return err
}
if err := setUp(d); err != nil {
return err
}
actualBitrate, err := d.Bitrate()
if err != nil {
return err
}
if err := setDown(d); err != nil {
return err
}
if actualBitrate != bitrate {
return fmt.Errorf("expected bitrate: %d, actual: %d", bitrate, bitrate)
}
return nil
}

func setUp(d *Device) error {
if err := d.SetUp(); err != nil {
return err
}

isUp, err := d.IsUp()
if err != nil {
return err
}
if !isUp {
return fmt.Errorf("device not up after calling SetUp()")
}
return nil
}

func setDown(d *Device) error {
if err := d.SetDown(); err != nil {
return err
}
isUp, err := d.IsUp()
if err != nil {
return err
}
if isUp {
return fmt.Errorf("device not down after calling SetDown()")
}
return nil
}
Loading

0 comments on commit 8d419f8

Please sign in to comment.