-
Notifications
You must be signed in to change notification settings - Fork 57
/
testhelper.go
134 lines (113 loc) · 3.46 KB
/
testhelper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Package testhelper provides helpers to ease mocking functions and methods
// provided by packages such as os or http.
package testhelper
import (
"fmt"
"io"
"io/fs"
"net/http"
"os"
)
// SaveCWD gets the current working directory and returns a function to go back to it
// nolint: errcheck
func SaveCWD() func() {
wd, _ := os.Getwd()
return func() {
_ = os.Chdir(wd)
}
}
// OSMockConf enables setting thresholds to indicate how many calls a the mocked
// functions should accept before returning an error.
// See osMock methods for specific behaviors.
type OSMockConf struct {
OsutilCopySpecialFileThreshold uint
ReadDirThreshold uint
RemoveThreshold uint
TruncateThreshold uint
OpenFileThreshold uint
MkdirAllThreshold uint
HttpGetThreshold uint
ReadAllThreshold uint
}
// osMock holds methods to easily mock functions from os and snapd/osutil packages
// Each method can be configured to fail after a given number of calls
// This could be improved by letting the mock functions calls the real
// functions before failing.
type osMock struct {
conf *OSMockConf
beforeOsutilCopySpecialFileFail uint
beforeReadDirFail uint
beforeRemoveFail uint
beforeTruncateFail uint
beforeOpenFileFail uint
beforeMkdirAllFail uint
beforeHttpGetFail uint
beforeReadAllFail uint
}
// CopySpecialFile mocks CopySpecialFile github.com/snapcore/snapd/osutil
func (o *osMock) CopySpecialFile(path, dest string) error {
if o.beforeOsutilCopySpecialFileFail >= o.conf.OsutilCopySpecialFileThreshold {
return fmt.Errorf("CopySpecialFile fail")
}
o.beforeOsutilCopySpecialFileFail++
return nil
}
// ReadDir mocks os.ReadDir
func (o *osMock) ReadDir(name string) ([]fs.DirEntry, error) {
if o.beforeReadDirFail >= o.conf.ReadDirThreshold {
return nil, fmt.Errorf("ReadDir fail")
}
o.beforeReadDirFail++
return []fs.DirEntry{}, nil
}
// Remove mocks os.Remove
func (o *osMock) Remove(name string) error {
if o.beforeRemoveFail >= o.conf.RemoveThreshold {
return fmt.Errorf("Remove fail")
}
o.beforeRemoveFail++
return nil
}
// Truncate mocks osTruncate
func (o *osMock) Truncate(name string, size int64) error {
if o.beforeTruncateFail >= o.conf.TruncateThreshold {
return fmt.Errorf("Truncate fail")
}
o.beforeTruncateFail++
return nil
}
// OpenFile mocks os.OpenFile
func (o *osMock) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
if o.beforeOpenFileFail >= o.conf.OpenFileThreshold {
return nil, fmt.Errorf("OpenFile fail")
}
o.beforeOpenFileFail++
return &os.File{}, nil
}
// MkdirAll mocks os.MkdirAll
func (o *osMock) MkdirAll(path string, perm os.FileMode) error {
if o.beforeOpenFileFail >= o.conf.OpenFileThreshold {
return fmt.Errorf("OpenFile fail")
}
o.beforeMkdirAllFail++
return nil
}
// HttpGet mocks http.Get
func (o *osMock) HttpGet(path string) (*http.Response, error) {
if o.beforeHttpGetFail >= o.conf.HttpGetThreshold {
return nil, fmt.Errorf("HttpGet fail")
}
o.beforeHttpGetFail++
return &http.Response{}, nil
}
// ReadAll mocks os.ReadAll
func (o *osMock) ReadAll(io.Reader) ([]byte, error) {
if o.beforeReadAllFail >= o.conf.ReadAllThreshold {
return nil, fmt.Errorf("ReadAll fail")
}
o.beforeReadAllFail++
return []byte{}, nil
}
func NewOSMock(conf *OSMockConf) *osMock {
return &osMock{conf: conf}
}