@@ -19,6 +19,7 @@ import (
19
19
"io"
20
20
"io/ioutil"
21
21
"os"
22
+ "path"
22
23
"path/filepath"
23
24
"reflect"
24
25
"testing"
@@ -150,6 +151,57 @@ func TestOpenAtIndex(t *testing.T) {
150
151
}
151
152
}
152
153
154
+ // TestVerify tests that Verify throws a non-nil error when the WAL is corrupted.
155
+ // The test creates a WAL directory and cuts out multiple WAL files. Then
156
+ // it corrupts one of the files by completely truncating it.
157
+ func TestVerify (t * testing.T ) {
158
+ walDir , err := ioutil .TempDir (os .TempDir (), "waltest" )
159
+ if err != nil {
160
+ t .Fatal (err )
161
+ }
162
+ defer os .RemoveAll (walDir )
163
+
164
+ // create WAL
165
+ w , err := Create (walDir , nil )
166
+ if err != nil {
167
+ t .Fatal (err )
168
+ }
169
+ defer w .Close ()
170
+
171
+ // make 5 separate files
172
+ for i := 0 ; i < 5 ; i ++ {
173
+ es := []raftpb.Entry {{Index : uint64 (i ), Data : []byte ("waldata" + string (i + 1 ))}}
174
+ if err = w .Save (raftpb.HardState {}, es ); err != nil {
175
+ t .Fatal (err )
176
+ }
177
+ if err = w .cut (); err != nil {
178
+ t .Fatal (err )
179
+ }
180
+ }
181
+
182
+ // to verify the WAL is not corrupted at this point
183
+ err = Verify (walDir , walpb.Snapshot {})
184
+ if err != nil {
185
+ t .Errorf ("expected a nil error, got %v" , err )
186
+ }
187
+
188
+ walFiles , err := ioutil .ReadDir (walDir )
189
+ if err != nil {
190
+ t .Fatal (err )
191
+ }
192
+
193
+ // corrupt the WAL by truncating one of the WAL files completely
194
+ err = os .Truncate (path .Join (walDir , walFiles [2 ].Name ()), 0 )
195
+ if err != nil {
196
+ t .Fatal (err )
197
+ }
198
+
199
+ err = Verify (walDir , walpb.Snapshot {})
200
+ if err == nil {
201
+ t .Error ("expected a non-nil error, got nil" )
202
+ }
203
+ }
204
+
153
205
// TODO: split it into smaller tests for better readability
154
206
func TestCut (t * testing.T ) {
155
207
p , err := ioutil .TempDir (os .TempDir (), "waltest" )
0 commit comments