@@ -10,6 +10,8 @@ import (
10
10
11
11
"github.com/stretchr/testify/require"
12
12
13
+ "go.uber.org/mock/gomock"
14
+
13
15
"github.com/ava-labs/avalanchego/database"
14
16
"github.com/ava-labs/avalanchego/database/memdb"
15
17
)
@@ -75,3 +77,124 @@ func TestCorruption(t *testing.T) {
75
77
})
76
78
}
77
79
}
80
+
81
+ func TestIterator (t * testing.T ) {
82
+ errIter := errors .New ("iterator error" )
83
+
84
+ type test struct {
85
+ name string
86
+ databaseErrBefore error
87
+ modifyIter func (* gomock.Controller , * iterator )
88
+ op func (* require.Assertions , * iterator )
89
+ expectedErr error
90
+ }
91
+
92
+ tests := []test {
93
+ {
94
+ name : "corrupted database; Next" ,
95
+ databaseErrBefore : errTest ,
96
+ expectedErr : errTest ,
97
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {},
98
+ op : func (require * require.Assertions , iter * iterator ) {
99
+ require .False (iter .Next ())
100
+ },
101
+ },
102
+ {
103
+ name : "Next corrupts database" ,
104
+ databaseErrBefore : nil ,
105
+ expectedErr : errIter ,
106
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {
107
+ mockInnerIter := database .NewMockIterator (ctrl )
108
+ mockInnerIter .EXPECT ().Next ().Return (false )
109
+ mockInnerIter .EXPECT ().Error ().Return (errIter )
110
+ iter .Iterator = mockInnerIter
111
+ },
112
+ op : func (require * require.Assertions , iter * iterator ) {
113
+ require .False (iter .Next ())
114
+ },
115
+ },
116
+ {
117
+ name : "corrupted database; Error" ,
118
+ databaseErrBefore : errTest ,
119
+ expectedErr : errTest ,
120
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {},
121
+ op : func (require * require.Assertions , iter * iterator ) {
122
+ err := iter .Error ()
123
+ require .ErrorIs (err , errTest )
124
+ },
125
+ },
126
+ {
127
+ name : "Error corrupts database" ,
128
+ databaseErrBefore : nil ,
129
+ expectedErr : errIter ,
130
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {
131
+ mockInnerIter := database .NewMockIterator (ctrl )
132
+ mockInnerIter .EXPECT ().Error ().Return (errIter )
133
+ iter .Iterator = mockInnerIter
134
+ },
135
+ op : func (require * require.Assertions , iter * iterator ) {
136
+ err := iter .Error ()
137
+ require .ErrorIs (err , errIter )
138
+ },
139
+ },
140
+ {
141
+ name : "corrupted database; Key" ,
142
+ databaseErrBefore : errTest ,
143
+ expectedErr : errTest ,
144
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {},
145
+ op : func (require * require.Assertions , iter * iterator ) {
146
+ _ = iter .Key ()
147
+ },
148
+ },
149
+ {
150
+ name : "corrupted database; Value" ,
151
+ databaseErrBefore : errTest ,
152
+ expectedErr : errTest ,
153
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {},
154
+ op : func (require * require.Assertions , iter * iterator ) {
155
+ _ = iter .Value ()
156
+ },
157
+ },
158
+ {
159
+ name : "corrupted database; Release" ,
160
+ databaseErrBefore : errTest ,
161
+ expectedErr : errTest ,
162
+ modifyIter : func (ctrl * gomock.Controller , iter * iterator ) {},
163
+ op : func (require * require.Assertions , iter * iterator ) {
164
+ iter .Release ()
165
+ },
166
+ },
167
+ }
168
+
169
+ for _ , tt := range tests {
170
+ t .Run (tt .name , func (t * testing.T ) {
171
+ require := require .New (t )
172
+ ctrl := gomock .NewController (t )
173
+
174
+ // Make a database
175
+ baseDB := memdb .New ()
176
+ corruptableDB := New (baseDB )
177
+
178
+ // Put a key-value pair in the database.
179
+ require .NoError (corruptableDB .Put ([]byte {0 }, []byte {1 }))
180
+
181
+ // Mark database as corupted, if applicable
182
+ _ = corruptableDB .handleError (tt .databaseErrBefore )
183
+
184
+ // Make an iterator
185
+ iter := & iterator {
186
+ Iterator : corruptableDB .NewIterator (),
187
+ db : corruptableDB ,
188
+ }
189
+
190
+ // Modify the iterator (optional)
191
+ tt .modifyIter (ctrl , iter )
192
+
193
+ // Do an iterator operation
194
+ tt .op (require , iter )
195
+
196
+ err := corruptableDB .corrupted ()
197
+ require .ErrorIs (err , tt .expectedErr )
198
+ })
199
+ }
200
+ }
0 commit comments