Skip to content

Commit 8d419f8

Browse files
Hashem Hashemhashemmm96
authored andcommitted
feat: add functionality for setting up CAN devices
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.
1 parent 0278ae5 commit 8d419f8

9 files changed

Lines changed: 676 additions & 11 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
.idea
22
tools/*/*/
33
build/
4+
5+
# files generated during release
6+
.generated-go-semantic-release-changelog.md
7+
.semrel/

.sage/main.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,21 @@ func GenerateTestdata(ctx context.Context) error {
126126
cmd.Dir = sg.FromGitRoot()
127127
return cmd.Run()
128128
}
129+
130+
func BuildIntegrationTests(ctx context.Context) error {
131+
sg.Logger(ctx).Println("building integration test...")
132+
testDir := sg.FromGitRoot("build", "tests")
133+
if err := os.MkdirAll(testDir, 0o775); err != nil {
134+
return err
135+
}
136+
return sg.Command(
137+
ctx,
138+
"go",
139+
"test",
140+
"-tags=integration",
141+
"-c",
142+
sg.FromGitRoot("pkg", "candevice"),
143+
"-o",
144+
filepath.Join(testDir, "candevice.test"),
145+
).Run()
146+
}

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ update-sage: $(go)
4343
clean-sage:
4444
@git clean -fdx .sage/tools .sage/bin .sage/build
4545

46+
.PHONY: build-integration-tests
47+
build-integration-tests: $(sagefile)
48+
@$(sagefile) BuildIntegrationTests
49+
4650
.PHONY: convco-check
4751
convco-check: $(sagefile)
4852
@$(sagefile) ConvcoCheck

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,21 @@ var auxMsg *etruckcan.Auxiliary
7575
_ = auxMsg.UnmarshalFrame(frame)
7676

7777
```
78+
79+
Running integration tests
80+
-------------------------
81+
82+
Building the tests:
83+
84+
```
85+
$ make build-integration-tests
86+
```
87+
88+
Built tests are placed in build/tests.
89+
90+
The candevice test requires access to physical HW, so run it using sudo. Example:
91+
92+
```
93+
$ ./build/tests/candevice.test
94+
> PASS
95+
```

go.mod

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ require (
66
github.com/davecgh/go-spew v1.1.1
77
github.com/fatih/color v1.13.0
88
github.com/golang/mock v1.6.0
9+
github.com/mdlayher/netlink v1.7.0
910
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041
1011
go.uber.org/goleak v1.1.12
11-
golang.org/x/net v0.0.0-20220923203811-8be639271d50
12-
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7
13-
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
12+
golang.org/x/net v0.2.0
13+
golang.org/x/sync v0.1.0
14+
golang.org/x/sys v0.2.0
1415
golang.org/x/tools v0.1.10
1516
gopkg.in/alecthomas/kingpin.v2 v2.2.6
1617
gotest.tools/v3 v3.4.0
@@ -19,9 +20,11 @@ require (
1920
require (
2021
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
2122
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
22-
github.com/google/go-cmp v0.5.5 // indirect
23+
github.com/google/go-cmp v0.5.9 // indirect
24+
github.com/josharian/native v1.0.0 // indirect
2325
github.com/mattn/go-colorable v0.1.9 // indirect
2426
github.com/mattn/go-isatty v0.0.14 // indirect
27+
github.com/mdlayher/socket v0.4.0 // indirect
2528
github.com/shurcooL/go v0.0.0-20190704215121-7189cc372560 // indirect
2629
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
2730
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect

go.sum

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
99
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
1010
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
1111
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
12-
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
1312
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
13+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
14+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
15+
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
16+
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
1417
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
1518
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
1619
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -19,6 +22,10 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
1922
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
2023
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
2124
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
25+
github.com/mdlayher/netlink v1.7.0 h1:ZNGI4V7i1fJ94DPYtWhI/R85i/Q7ZxnuhUJQcJMoodI=
26+
github.com/mdlayher/netlink v1.7.0/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
27+
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
28+
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
2229
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2330
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2431
github.com/shurcooL/go v0.0.0-20190704215121-7189cc372560 h1:SpaoQDTgpo2YZkvmr2mtgloFFfPTjtLMlZkQtNAPQik=
@@ -47,13 +54,13 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
4754
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
4855
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
4956
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
50-
golang.org/x/net v0.0.0-20220923203811-8be639271d50 h1:vKyz8L3zkd+xrMeIaBsQ/MNVPVFSffdaU3ZyYlBGFnI=
51-
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
57+
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
58+
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
5259
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5360
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5461
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
55-
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
56-
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
62+
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
63+
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5764
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5865
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5966
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -64,8 +71,8 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
6471
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6572
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
6673
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
67-
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
68-
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
74+
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
75+
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
6976
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
7077
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
7178
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//go:build integration
2+
3+
package candevice
4+
5+
import (
6+
"fmt"
7+
"testing"
8+
)
9+
10+
const (
11+
bitrate125K = 125000
12+
bitrate250K = 250000
13+
)
14+
15+
func TestSetBitrate(t *testing.T) {
16+
d, err := New("can0")
17+
if err != nil {
18+
t.Fatal("couldn't set up device:", err)
19+
}
20+
defer d.SetDown()
21+
22+
if err := setBitrate(d, bitrate125K); err != nil {
23+
t.Fatal(err)
24+
}
25+
if err := setBitrate(d, bitrate250K); err != nil {
26+
t.Fatal(err)
27+
}
28+
29+
// Set bitrate on device which is up
30+
if err := d.SetUp(); err != nil {
31+
t.Fatal(err)
32+
}
33+
if err := setBitrate(d, bitrate125K); err == nil {
34+
t.Fatal("setting bitrate on device which is up succeeded")
35+
}
36+
if err := d.SetDown(); err != nil {
37+
t.Fatal(err)
38+
}
39+
40+
// Invalid bitrate
41+
if err := setBitrate(d, 0); err == nil {
42+
t.Fatal("setting invalid bitrate succeeded")
43+
}
44+
}
45+
46+
func TestSetUpDown(t *testing.T) {
47+
d, err := New("can0")
48+
if err != nil {
49+
t.Fatal("couldn't set up device:", err)
50+
}
51+
defer d.SetDown()
52+
53+
if err := d.SetBitrate(bitrate125K); err != nil {
54+
t.Fatal(err)
55+
}
56+
57+
// Set up twice and set down twice. This checks that calling it twice has no effect
58+
if err := setUp(d); err != nil {
59+
t.Fatal(err)
60+
}
61+
if err := setUp(d); err != nil {
62+
t.Fatal(err)
63+
}
64+
if err := setDown(d); err != nil {
65+
t.Fatal(err)
66+
}
67+
if err := setDown(d); err != nil {
68+
t.Fatal(err)
69+
}
70+
}
71+
72+
func setBitrate(d *Device, bitrate uint32) error {
73+
if err := d.SetBitrate(bitrate); err != nil {
74+
return err
75+
}
76+
if err := setUp(d); err != nil {
77+
return err
78+
}
79+
actualBitrate, err := d.Bitrate()
80+
if err != nil {
81+
return err
82+
}
83+
if err := setDown(d); err != nil {
84+
return err
85+
}
86+
if actualBitrate != bitrate {
87+
return fmt.Errorf("expected bitrate: %d, actual: %d", bitrate, bitrate)
88+
}
89+
return nil
90+
}
91+
92+
func setUp(d *Device) error {
93+
if err := d.SetUp(); err != nil {
94+
return err
95+
}
96+
97+
isUp, err := d.IsUp()
98+
if err != nil {
99+
return err
100+
}
101+
if !isUp {
102+
return fmt.Errorf("device not up after calling SetUp()")
103+
}
104+
return nil
105+
}
106+
107+
func setDown(d *Device) error {
108+
if err := d.SetDown(); err != nil {
109+
return err
110+
}
111+
isUp, err := d.IsUp()
112+
if err != nil {
113+
return err
114+
}
115+
if isUp {
116+
return fmt.Errorf("device not down after calling SetDown()")
117+
}
118+
return nil
119+
}

0 commit comments

Comments
 (0)