/
dependencies.go
137 lines (111 loc) · 4.64 KB
/
dependencies.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
135
136
137
package pool
import (
"errors"
"io/ioutil"
"net"
"os"
"SiaPrime/persist"
"gitlab.com/NebulousLabs/fastrand"
)
// Fake errors that get returned when a simulated failure of a dependency is
// desired for testing.
var (
mockErrListen = errors.New("simulated Listen failure")
mockErrLoadFile = errors.New("simulated LoadFile failure")
mockErrMkdirAll = errors.New("simulated MkdirAll failure")
mockErrNewLogger = errors.New("simulated NewLogger failure")
mockErrOpenDatabase = errors.New("simulated OpenDatabase failure")
mockErrReadFile = errors.New("simulated ReadFile failure")
mockErrRemoveFile = errors.New("simulated RemoveFile faulure")
mockErrSymlink = errors.New("simulated Symlink failure")
mockErrWriteFile = errors.New("simulated WriteFile failure")
)
// These interfaces define the Pool's dependencies. Mocking implementation
// complexity can be reduced by defining each dependency as the minimum
// possible subset of the real dependency.
type (
// dependencies defines all of the dependencies of the Pool.
dependencies interface {
// disrupt can be inserted in the code as a way to inject problems,
// such as a network call that take 10 minutes or a disk write that
// never completes. disrupt will return true if the disruption is
// forcibly triggered. In production, disrupt will always return false.
disrupt(string) bool
// listen gives the host the ability to receive incoming connections.
listen(string, string) (net.Listener, error)
// loadFile allows the host to load a persistence structure form disk.
loadFile(persist.Metadata, interface{}, string) error
// mkdirAll gives the host the ability to create chains of folders
// within the filesystem.
mkdirAll(string, os.FileMode) error
// newLogger creates a logger that the host can use to log messages and
// write critical statements.
newLogger(string) (*persist.Logger, error)
// openDatabase creates a database that the host can use to interact
// with large volumes of persistent data.
openDatabase(persist.Metadata, string) (*persist.BoltDatabase, error)
// randRead fills the input bytes with random data.
randRead([]byte) (int, error)
// readFile reads a file in full from the filesystem.
readFile(string) ([]byte, error)
// removeFile removes a file from file filesystem.
removeFile(string) error
// symlink creates a sym link between a source and a destination.
symlink(s1, s2 string) error
// writeFile writes data to the filesystem using the provided filename.
writeFile(string, []byte, os.FileMode) error
}
)
type (
// productionDependencies is an empty struct that implements all of the
// dependencies using full featured libraries.
productionDependencies struct{}
)
// disrupt will always return false, but can be over-written during testing to
// trigger disruptions.
func (productionDependencies) disrupt(string) bool {
return false
}
// listen gives the host the ability to receive incoming connections.
func (productionDependencies) listen(s1, s2 string) (net.Listener, error) {
return net.Listen(s1, s2)
}
// loadFile allows the host to load a persistence structure form disk.
func (productionDependencies) loadFile(m persist.Metadata, i interface{}, s string) error {
return persist.LoadJSON(m, i, s)
}
// mkdirAll gives the host the ability to create chains of folders within the
// filesystem.
func (productionDependencies) mkdirAll(s string, fm os.FileMode) error {
return os.MkdirAll(s, fm)
}
// newLogger creates a logger that the host can use to log messages and write
// critical statements.
func (productionDependencies) newLogger(s string) (*persist.Logger, error) {
return persist.NewFileLogger(s)
}
// openDatabase creates a database that the host can use to interact with large
// volumes of persistent data.
func (productionDependencies) openDatabase(m persist.Metadata, s string) (*persist.BoltDatabase, error) {
return persist.OpenDatabase(m, s)
}
// randRead fills the input bytes with random data.
func (productionDependencies) randRead(b []byte) (int, error) {
return fastrand.Reader.Read(b)
}
// readFile reads a file from the filesystem.
func (productionDependencies) readFile(s string) ([]byte, error) {
return ioutil.ReadFile(s)
}
// removeFile removes a file from the filesystem.
func (productionDependencies) removeFile(s string) error {
return os.Remove(s)
}
// symlink creates a symlink between a source and a destination file.
func (productionDependencies) symlink(s1, s2 string) error {
return os.Symlink(s1, s2)
}
// writeFile writes a file to the filesystem.
func (productionDependencies) writeFile(s string, b []byte, fm os.FileMode) error {
return ioutil.WriteFile(s, b, fm)
}