5
5
import java .io .IOException ;
6
6
import java .io .InputStream ;
7
7
8
+ import io .objectbox .exception .FileCorruptException ;
8
9
import io .objectbox .exception .PagesCorruptException ;
9
10
import io .objectbox .model .ValidateOnOpenMode ;
10
11
import org .greenrobot .essentials .io .IoUtils ;
11
12
import org .junit .Before ;
12
13
import org .junit .Test ;
13
14
15
+ import static org .junit .Assert .assertEquals ;
14
16
import static org .junit .Assert .assertNotNull ;
17
+ import static org .junit .Assert .assertThrows ;
15
18
import static org .junit .Assert .assertTrue ;
16
19
import static org .junit .Assert .fail ;
17
20
@@ -38,14 +41,7 @@ public void setUpBuilder() {
38
41
public void validateOnOpen () {
39
42
// Create a database first; we must create the model only once (ID/UID sequences would be different 2nd time)
40
43
byte [] model = createTestModel (null );
41
- builder = new BoxStoreBuilder (model ).directory (boxStoreDir );
42
- builder .entity (new TestEntity_ ());
43
- store = builder .build ();
44
-
45
- TestEntity object = new TestEntity (0 );
46
- object .setSimpleString ("hello hello" );
47
- long id = getTestEntityBox ().put (object );
48
- store .close ();
44
+ long id = buildNotCorruptedDatabase (model );
49
45
50
46
// Then re-open database with validation and ensure db is operational
51
47
builder = new BoxStoreBuilder (model ).directory (boxStoreDir );
@@ -57,27 +53,26 @@ public void validateOnOpen() {
57
53
}
58
54
59
55
60
- @ Test ( expected = PagesCorruptException . class )
56
+ @ Test
61
57
public void validateOnOpenCorruptFile () throws IOException {
62
58
File dir = prepareTempDir ("object-store-test-corrupted" );
63
- File badDataFile = prepareBadDataFile (dir );
59
+ prepareBadDataFile (dir , "corrupt-pageno-in-branch-data.mdb" );
64
60
65
61
builder = BoxStoreBuilder .createDebugWithoutModel ().directory (dir );
66
62
builder .validateOnOpen (ValidateOnOpenMode .Full );
67
- try {
68
- store = builder .build ();
69
- } finally {
70
- boolean delOk = badDataFile .delete ();
71
- delOk &= new File (dir , "lock.mdb" ).delete ();
72
- delOk &= dir .delete ();
73
- assertTrue (delOk ); // Try to delete all before asserting
74
- }
63
+
64
+ @ SuppressWarnings ("resource" )
65
+ FileCorruptException ex = assertThrows (PagesCorruptException .class , () -> builder .build ());
66
+ assertEquals ("Validating pages failed (page not found)" , ex .getMessage ());
67
+
68
+ // Clean up
69
+ deleteAllFiles (dir );
75
70
}
76
71
77
72
@ Test
78
73
public void usePreviousCommitWithCorruptFile () throws IOException {
79
74
File dir = prepareTempDir ("object-store-test-corrupted" );
80
- prepareBadDataFile (dir );
75
+ prepareBadDataFile (dir , "corrupt-pageno-in-branch-data.mdb" );
81
76
builder = BoxStoreBuilder .createDebugWithoutModel ().directory (dir );
82
77
builder .validateOnOpen (ValidateOnOpenMode .Full ).usePreviousCommit ();
83
78
store = builder .build ();
@@ -91,7 +86,7 @@ public void usePreviousCommitWithCorruptFile() throws IOException {
91
86
@ Test
92
87
public void usePreviousCommitAfterFileCorruptException () throws IOException {
93
88
File dir = prepareTempDir ("object-store-test-corrupted" );
94
- prepareBadDataFile (dir );
89
+ prepareBadDataFile (dir , "corrupt-pageno-in-branch-data.mdb" );
95
90
builder = BoxStoreBuilder .createDebugWithoutModel ().directory (dir );
96
91
builder .validateOnOpen (ValidateOnOpenMode .Full );
97
92
try {
@@ -109,15 +104,65 @@ public void usePreviousCommitAfterFileCorruptException() throws IOException {
109
104
assertTrue (store .deleteAllFiles ());
110
105
}
111
106
112
- private File prepareBadDataFile (File dir ) throws IOException {
107
+ @ Test
108
+ public void validateOnOpenKv () {
109
+ // Create a database first; we must create the model only once (ID/UID sequences would be different 2nd time)
110
+ byte [] model = createTestModel (null );
111
+ long id = buildNotCorruptedDatabase (model );
112
+
113
+ // Then re-open database with validation and ensure db is operational
114
+ builder = new BoxStoreBuilder (model ).directory (boxStoreDir );
115
+ builder .entity (new TestEntity_ ());
116
+ builder .validateOnOpenKv ();
117
+ store = builder .build ();
118
+ assertNotNull (getTestEntityBox ().get (id ));
119
+ getTestEntityBox ().put (new TestEntity (0 ));
120
+ }
121
+
122
+ @ Test
123
+ public void validateOnOpenKvCorruptFile () throws IOException {
124
+ File dir = prepareTempDir ("obx-store-validate-kv-corrupted" );
125
+ prepareBadDataFile (dir , "corrupt-keysize0-data.mdb" );
126
+
127
+ builder = BoxStoreBuilder .createDebugWithoutModel ().directory (dir );
128
+ builder .validateOnOpenKv ();
129
+
130
+ @ SuppressWarnings ("resource" )
131
+ FileCorruptException ex = assertThrows (FileCorruptException .class , () -> builder .build ());
132
+ assertEquals ("KV validation failed; key is empty (KV pair number: 1, key size: 0, data size: 112)" ,
133
+ ex .getMessage ());
134
+
135
+ // Clean up
136
+ deleteAllFiles (dir );
137
+ }
138
+
139
+ /**
140
+ * Returns the id of the inserted test entity.
141
+ */
142
+ private long buildNotCorruptedDatabase (byte [] model ) {
143
+ builder = new BoxStoreBuilder (model ).directory (boxStoreDir );
144
+ builder .entity (new TestEntity_ ());
145
+ store = builder .build ();
146
+
147
+ TestEntity object = new TestEntity (0 );
148
+ object .setSimpleString ("hello hello" );
149
+ long id = getTestEntityBox ().put (object );
150
+ store .close ();
151
+ return id ;
152
+ }
153
+
154
+ /**
155
+ * Copies the given file from resources to the given directory as "data.mdb".
156
+ */
157
+ private void prepareBadDataFile (File dir , String resourceName ) throws IOException {
113
158
assertTrue (dir .mkdir ());
114
159
File badDataFile = new File (dir , "data.mdb" );
115
- try (InputStream badIn = getClass ().getResourceAsStream ("corrupt-pageno-in-branch-data.mdb" )) {
160
+ try (InputStream badIn = getClass ().getResourceAsStream (resourceName )) {
161
+ assertNotNull (badIn );
116
162
try (FileOutputStream badOut = new FileOutputStream (badDataFile )) {
117
163
IoUtils .copyAllBytes (badIn , badOut );
118
164
}
119
165
}
120
- return badDataFile ;
121
166
}
122
167
123
168
}
0 commit comments