Skip to content

Commit 67f813c

Browse files
committed
internal tests
1 parent d37a1f1 commit 67f813c

File tree

4 files changed

+191
-23
lines changed

4 files changed

+191
-23
lines changed

coderd/audit/diff.go

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,41 @@ func Empty[T Auditable]() T {
1313
return t
1414
}
1515

16-
func Diff[T Auditable](old, new T) DiffMap {
16+
// Diff compares two auditable resources and produces a map
17+
func Diff[T Auditable](left, right T) DiffMap {
1718
// Values are equal, return an empty diff.
18-
if reflect.DeepEqual(old, new) {
19+
if reflect.DeepEqual(left, right) {
1920
return DiffMap{}
2021
}
2122

22-
return diffValues(old, new)
23+
return diffValues(left, right, AuditableResources)
2324
}
2425

25-
func diffValues[T any](old, new T) DiffMap {
26+
func diffValues[T any](left, right T, table Map) DiffMap {
2627
var (
2728
baseDiff = DiffMap{}
2829

29-
oldV = reflect.ValueOf(old)
30+
leftV = reflect.ValueOf(left)
3031

31-
newV = reflect.ValueOf(new)
32-
newT = reflect.TypeOf(new)
32+
rightV = reflect.ValueOf(right)
33+
rightT = reflect.TypeOf(right)
3334

34-
diffKey = AuditableResources[newT.Name()]
35+
diffKey = table[rightT.Name()]
3536
)
3637

3738
if diffKey == nil {
38-
panic(fmt.Sprintf("dev error: type %T attempted audit but not auditable", new))
39+
panic(fmt.Sprintf("dev error: type %q (type %T) attempted audit but not auditable", rightT.Name(), right))
3940
}
4041

41-
for i := 0; i < newT.NumField(); i++ {
42+
for i := 0; i < rightT.NumField(); i++ {
4243
var (
43-
oldF = oldV.Field(i)
44-
newF = newV.Field(i)
44+
leftF = leftV.Field(i)
45+
rightF = rightV.Field(i)
4546

46-
oldI = oldF.Interface()
47-
newI = newF.Interface()
47+
leftI = leftF.Interface()
48+
rightI = rightF.Interface()
4849

49-
diffName = newT.Field(i).Tag.Get("json")
50+
diffName = rightT.Field(i).Tag.Get("json")
5051
)
5152

5253
atype, ok := diffKey[diffName]
@@ -60,23 +61,23 @@ func diffValues[T any](old, new T) DiffMap {
6061

6162
// If the field is a pointer, dereference it. Nil pointers are coerced
6263
// to the zero value of their underlying type.
63-
if oldF.Kind() == reflect.Ptr && newF.Kind() == reflect.Ptr {
64-
oldF, newF = derefPointer(oldF), derefPointer(newF)
65-
oldI, newI = oldF.Interface(), newF.Interface()
64+
if leftF.Kind() == reflect.Ptr && rightF.Kind() == reflect.Ptr {
65+
leftF, rightF = derefPointer(leftF), derefPointer(rightF)
66+
leftI, rightI = leftF.Interface(), rightF.Interface()
6667
}
6768

6869
// Recursively walk up nested structs.
69-
if newF.Kind() == reflect.Struct {
70-
baseDiff[diffName] = diffValues(oldI, newI)
70+
if rightF.Kind() == reflect.Struct {
71+
baseDiff[diffName] = diffValues(leftI, rightI, table)
7172
continue
7273
}
7374

74-
if !reflect.DeepEqual(oldI, newI) {
75+
if !reflect.DeepEqual(leftI, rightI) {
7576
switch atype {
7677
case ActionTrack:
77-
baseDiff[diffName] = newI
78+
baseDiff[diffName] = rightI
7879
case ActionSecret:
79-
baseDiff[diffName] = reflect.Zero(newF.Type()).Interface()
80+
baseDiff[diffName] = reflect.Zero(rightF.Type()).Interface()
8081
}
8182
}
8283
}

coderd/audit/diff_internal_test.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package audit
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"k8s.io/utils/pointer"
8+
)
9+
10+
func Test_diffValues(t *testing.T) {
11+
t.Parallel()
12+
13+
t.Run("Normal", func(t *testing.T) {
14+
t.Parallel()
15+
16+
type foo struct {
17+
Bar string `json:"bar"`
18+
Baz int64 `json:"baz"`
19+
}
20+
21+
table := auditMap(map[any]map[string]Action{
22+
&foo{}: {
23+
"bar": ActionTrack,
24+
"baz": ActionTrack,
25+
},
26+
})
27+
28+
runDiffTests(t, table, []diffTest{
29+
{
30+
name: "LeftEmpty",
31+
left: foo{Bar: "", Baz: 0}, right: foo{Bar: "bar", Baz: 10},
32+
exp: DiffMap{
33+
"bar": "bar",
34+
"baz": int64(10),
35+
},
36+
},
37+
{
38+
name: "RightEmpty",
39+
left: foo{Bar: "Bar", Baz: 10}, right: foo{Bar: "", Baz: 0},
40+
exp: DiffMap{
41+
"bar": "",
42+
"baz": int64(0),
43+
},
44+
},
45+
{
46+
name: "NoChange",
47+
left: foo{Bar: "", Baz: 0}, right: foo{Bar: "", Baz: 0},
48+
exp: DiffMap{},
49+
},
50+
{
51+
name: "SingleFieldChange",
52+
left: foo{Bar: "", Baz: 0}, right: foo{Bar: "Bar", Baz: 0},
53+
exp: DiffMap{
54+
"bar": "Bar",
55+
},
56+
},
57+
})
58+
})
59+
60+
t.Run("PointerField", func(t *testing.T) {
61+
t.Parallel()
62+
63+
type foo struct {
64+
Bar *string `json:"bar"`
65+
}
66+
67+
table := auditMap(map[any]map[string]Action{
68+
&foo{}: {
69+
"bar": ActionTrack,
70+
},
71+
})
72+
73+
runDiffTests(t, table, []diffTest{
74+
{
75+
name: "LeftNil",
76+
left: foo{Bar: nil}, right: foo{Bar: pointer.StringPtr("baz")},
77+
exp: DiffMap{"bar": "baz"},
78+
},
79+
{
80+
name: "RightNil",
81+
left: foo{Bar: pointer.StringPtr("baz")}, right: foo{Bar: nil},
82+
exp: DiffMap{"bar": ""},
83+
},
84+
})
85+
})
86+
87+
t.Run("NestedStruct", func(t *testing.T) {
88+
t.Parallel()
89+
90+
type bar struct {
91+
Baz string `json:"baz"`
92+
}
93+
94+
type foo struct {
95+
Bar *bar `json:"bar"`
96+
}
97+
98+
table := auditMap(map[any]map[string]Action{
99+
&foo{}: {
100+
"bar": ActionTrack,
101+
},
102+
&bar{}: {
103+
"baz": ActionTrack,
104+
},
105+
})
106+
107+
runDiffTests(t, table, []diffTest{
108+
{
109+
name: "LeftEmpty",
110+
left: foo{Bar: &bar{}}, right: foo{Bar: &bar{Baz: "baz"}},
111+
exp: DiffMap{
112+
"bar": DiffMap{
113+
"baz": "baz",
114+
},
115+
},
116+
},
117+
{
118+
name: "RightEmpty",
119+
left: foo{Bar: &bar{Baz: "baz"}}, right: foo{Bar: &bar{}},
120+
exp: DiffMap{
121+
"bar": DiffMap{
122+
"baz": "",
123+
},
124+
},
125+
},
126+
{
127+
name: "LeftNil",
128+
left: foo{Bar: nil}, right: foo{Bar: &bar{}},
129+
exp: DiffMap{
130+
"bar": DiffMap{},
131+
},
132+
},
133+
{
134+
name: "RightNil",
135+
left: foo{Bar: &bar{Baz: "baz"}}, right: foo{Bar: nil},
136+
exp: DiffMap{
137+
"bar": DiffMap{
138+
"baz": "",
139+
},
140+
},
141+
},
142+
})
143+
})
144+
}
145+
146+
type diffTest struct {
147+
name string
148+
left, right any
149+
exp any
150+
}
151+
152+
func runDiffTests(t *testing.T, table Map, tests []diffTest) {
153+
t.Helper()
154+
155+
for _, test := range tests {
156+
t.Run(test.name, func(t *testing.T) {
157+
assert.Equal(t,
158+
test.exp,
159+
diffValues(test.left, test.right, table),
160+
)
161+
})
162+
}
163+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ require (
107107
google.golang.org/api v0.74.0
108108
google.golang.org/protobuf v1.28.0
109109
gopkg.in/DataDog/dd-trace-go.v1 v1.37.1
110+
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
110111
nhooyr.io/websocket v1.8.7
111112
storj.io/drpc v0.0.30
112113
)

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,10 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAG
24982498
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
24992499
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
25002500
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
2501+
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
25012502
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
2503+
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
2504+
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
25022505
mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ=
25032506
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
25042507
modernc.org/cc/v3 v3.32.4/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=

0 commit comments

Comments
 (0)