@@ -20,6 +20,7 @@ import (
20
20
"io/ioutil"
21
21
"math"
22
22
"os"
23
+ "path"
23
24
"path/filepath"
24
25
"reflect"
25
26
"testing"
@@ -186,6 +187,57 @@ func TestOpenAtIndex(t *testing.T) {
186
187
}
187
188
}
188
189
190
+ // TestVerify tests that Verify throws a non-nil error when the WAL is corrupted.
191
+ // The test creates a WAL directory and cuts out multiple WAL files. Then
192
+ // it corrupts one of the files by completely truncating it.
193
+ func TestVerify (t * testing.T ) {
194
+ walDir , err := ioutil .TempDir (os .TempDir (), "waltest" )
195
+ if err != nil {
196
+ t .Fatal (err )
197
+ }
198
+ defer os .RemoveAll (walDir )
199
+
200
+ // create WAL
201
+ w , err := Create (zap .NewExample (), walDir , nil )
202
+ if err != nil {
203
+ t .Fatal (err )
204
+ }
205
+ defer w .Close ()
206
+
207
+ // make 5 separate files
208
+ for i := 0 ; i < 5 ; i ++ {
209
+ es := []raftpb.Entry {{Index : uint64 (i ), Data : []byte ("waldata" + string (i + 1 ))}}
210
+ if err = w .Save (raftpb.HardState {}, es ); err != nil {
211
+ t .Fatal (err )
212
+ }
213
+ if err = w .cut (); err != nil {
214
+ t .Fatal (err )
215
+ }
216
+ }
217
+
218
+ // to verify the WAL is not corrupted at this point
219
+ err = Verify (zap .NewExample (), walDir , walpb.Snapshot {})
220
+ if err != nil {
221
+ t .Errorf ("expected a nil error, got %v" , err )
222
+ }
223
+
224
+ walFiles , err := ioutil .ReadDir (walDir )
225
+ if err != nil {
226
+ t .Fatal (err )
227
+ }
228
+
229
+ // corrupt the WAL by truncating one of the WAL files completely
230
+ err = os .Truncate (path .Join (walDir , walFiles [2 ].Name ()), 0 )
231
+ if err != nil {
232
+ t .Fatal (err )
233
+ }
234
+
235
+ err = Verify (zap .NewExample (), walDir , walpb.Snapshot {})
236
+ if err == nil {
237
+ t .Error ("expected a non-nil error, got nil" )
238
+ }
239
+ }
240
+
189
241
// TODO: split it into smaller tests for better readability
190
242
func TestCut (t * testing.T ) {
191
243
p , err := ioutil .TempDir (os .TempDir (), "waltest" )
0 commit comments