@@ -3,6 +3,7 @@ package oplog
3
3
import (
4
4
"bytes"
5
5
"context"
6
+ "fmt"
6
7
"io"
7
8
"os"
8
9
"path/filepath"
@@ -11,6 +12,7 @@ import (
11
12
"github.com/mongodb/mongo-tools/common/db"
12
13
"github.com/mongodb/mongo-tools/common/idx"
13
14
"github.com/mongodb/mongo-tools/mongorestore/ns"
15
+ "github.com/pkg/errors"
14
16
"go.mongodb.org/mongo-driver/bson"
15
17
"go.mongodb.org/mongo-driver/bson/primitive"
16
18
@@ -33,6 +35,11 @@ func newOplogRestoreTest(mdb mDBCl) *OplogRestore {
33
35
}
34
36
35
37
type mdbTestClient struct {
38
+ applyOpsInv []map [string ]string
39
+ }
40
+
41
+ func newMDBTestClient () * mdbTestClient {
42
+ return & mdbTestClient {applyOpsInv : []map [string ]string {}}
36
43
}
37
44
38
45
func (d * mdbTestClient ) getUUIDForNS (_ context.Context , _ string ) (primitive.Binary , error ) {
@@ -44,6 +51,17 @@ func (d *mdbTestClient) ensureCollExists(_ string) error {
44
51
}
45
52
46
53
func (d * mdbTestClient ) applyOps (entries []interface {}) error {
54
+ if len (entries ) != 1 {
55
+ return errors .New ("applyOps without single oplog entry" )
56
+ }
57
+
58
+ oe := entries [0 ].(db.Oplog )
59
+ invParams := map [string ]string {
60
+ "op" : oe .Operation ,
61
+ "ns" : oe .Namespace ,
62
+ }
63
+ d .applyOpsInv = append (d .applyOpsInv , invParams )
64
+
47
65
return nil
48
66
}
49
67
@@ -121,31 +139,94 @@ func TestIsOpForCloning(t *testing.T) {
121
139
}
122
140
123
141
func TestApply (t * testing.T ) {
124
- oRestore := newOplogRestoreTest (& mdbTestClient {})
125
- oRestore .SetCloneNS (context .Background (), snapshot.CloneNS {FromNS : "mydb.c5" , ToNS : "mydb.c5" })
126
-
127
- fr := useTestFile (t , "oplog_test.json" )
128
-
129
- lts , err := oRestore .Apply (fr )
130
- if err != nil {
131
- t .Fatal (err )
132
- }
133
-
134
- t .Log (lts )
142
+ t .Run ("oplog restore" , func (t * testing.T ) {
143
+ //todo:
144
+ })
145
+
146
+ t .Run ("selective restore" , func (t * testing.T ) {
147
+ //todo:
148
+ })
149
+
150
+ t .Run ("cloning namespace" , func (t * testing.T ) {
151
+ testCases := []struct {
152
+ desc string
153
+ oplogFile string
154
+ nsFrom string
155
+ nsTo string
156
+ resOps []string
157
+ resNS []string
158
+ }{
159
+ {
160
+ desc : "clone: insert, update, delete ops" ,
161
+ oplogFile : "ops_i_u_d" ,
162
+ nsFrom : "mydb.c1" ,
163
+ nsTo : "mydb.c1_clone" ,
164
+ resOps : []string {"i" , "u" , "d" },
165
+ resNS : []string {"mydb.c1_clone" , "mydb.c1_clone" , "mydb.c1_clone" },
166
+ },
167
+ {
168
+ desc : "ignore namespaces not relevent for cloning" ,
169
+ oplogFile : "ops_i_u_d" ,
170
+ nsFrom : "mydb.xyz" ,
171
+ nsTo : "mydb.xyz_clone" ,
172
+ resOps : []string {},
173
+ resNS : []string {},
174
+ },
175
+ {
176
+ desc : "ignore noop op" ,
177
+ oplogFile : "ops_n" ,
178
+ nsFrom : "mydb.xyz" ,
179
+ nsTo : "mydb.xyz_clone" ,
180
+ resOps : []string {},
181
+ resNS : []string {},
182
+ },
183
+ }
184
+ for _ , tC := range testCases {
185
+ t .Run (tC .desc , func (t * testing.T ) {
186
+ db := newMDBTestClient ()
187
+ oRestore := newOplogRestoreTest (db )
188
+ oRestore .SetCloneNS (context .Background (), snapshot.CloneNS {FromNS : tC .nsFrom , ToNS : tC .nsTo })
189
+
190
+ fr := useTestFile (t , tC .oplogFile )
191
+
192
+ _ , err := oRestore .Apply (fr )
193
+ if err != nil {
194
+ t .Fatalf ("error while applying oplog: %v" , err )
195
+ }
196
+
197
+ if len (tC .resOps ) != len (db .applyOpsInv ) {
198
+ t .Errorf ("wrong number of applyOps invocation, want=%d, got=%d" , len (tC .resOps ), len (db .applyOpsInv ))
199
+ }
200
+ for i , wantOp := range tC .resOps {
201
+ gotOp := db .applyOpsInv [i ]["op" ]
202
+ if wantOp != gotOp {
203
+ t .Errorf ("wrong #%d. operation: want=%s, got=%s" , i , wantOp , gotOp )
204
+ }
205
+ }
206
+ for i , wantNS := range tC .resNS {
207
+ gotNS := db .applyOpsInv [i ]["ns" ]
208
+ if wantNS != gotNS {
209
+ t .Errorf ("wrong #%d. namespace: want=%s, got=%s" , i , wantNS , gotNS )
210
+ }
211
+ }
212
+ })
213
+ }
214
+ })
135
215
}
136
216
137
217
func useTestFile (t * testing.T , testFileName string ) io.ReadCloser {
138
218
t .Helper ()
139
219
140
- jsonData , err := os .ReadFile (filepath .Join ("./testdata" , testFileName ))
220
+ f := fmt .Sprintf ("%s.json" , testFileName )
221
+ jsonData , err := os .ReadFile (filepath .Join ("./testdata" , f ))
141
222
if err != nil {
142
- t .Fatalf ("failed to read test json file: filename=%s, err=%v" , testFileName , err )
223
+ t .Fatalf ("failed to read test json file: filename=%s, err=%v" , f , err )
143
224
}
144
225
145
226
var jsonDocs []map [string ]interface {}
146
227
err = bson .UnmarshalExtJSON (jsonData , false , & jsonDocs )
147
228
if err != nil {
148
- t .Fatalf ("failed to parse test json array: filename=%s, err=%v" , testFileName , err )
229
+ t .Fatalf ("failed to parse test json array: filename=%s, err=%v" , f , err )
149
230
}
150
231
151
232
b := & bytes.Buffer {}
0 commit comments