github.com/apache/beam/sdks/v2@v2.48.2/go/test/integration/io/mongodbio/mongodbio_test.go (about) 1 // Licensed to the Apache Software Foundation (ASF) under one or more 2 // contributor license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright ownership. 4 // The ASF licenses this file to You under the Apache License, Version 2.0 5 // (the "License"); you may not use this file except in compliance with 6 // the License. You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package mongodbio 17 18 import ( 19 "context" 20 "flag" 21 "fmt" 22 "reflect" 23 "testing" 24 25 "github.com/apache/beam/sdks/v2/go/pkg/beam" 26 "github.com/apache/beam/sdks/v2/go/pkg/beam/io/mongodbio" 27 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/dataflow" 28 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/flink" 29 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/samza" 30 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/spark" 31 "github.com/apache/beam/sdks/v2/go/pkg/beam/testing/passert" 32 "github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest" 33 "github.com/apache/beam/sdks/v2/go/test/integration" 34 "github.com/google/go-cmp/cmp" 35 "go.mongodb.org/mongo-driver/bson" 36 "go.mongodb.org/mongo-driver/bson/primitive" 37 ) 38 39 func init() { 40 beam.RegisterType(reflect.TypeOf((*docWithObjectID)(nil)).Elem()) 41 beam.RegisterType(reflect.TypeOf((*docWithStringID)(nil)).Elem()) 42 } 43 44 type docWithObjectID struct { 45 ID primitive.ObjectID `bson:"_id"` 46 Field1 int32 `bson:"field1"` 47 } 48 49 type docWithStringID struct { 50 ID string `bson:"_id"` 51 Field1 int32 `bson:"field1"` 52 } 53 54 func TestMongoDBIO_Read(t *testing.T) { 55 integration.CheckFilters(t) 56 57 ctx := context.Background() 58 port := setUpTestContainer(ctx, t) 59 uri := fmt.Sprintf("mongodb://%s:%s", "localhost", port) 60 61 tests := []struct { 62 name string 63 input []any 64 t reflect.Type 65 options []mongodbio.ReadOptionFn 66 want []any 67 }{ 68 { 69 name: "Read documents from MongoDB with id of type primitive.ObjectID", 70 input: []any{ 71 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), "field1": int32(0)}, 72 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), "field1": int32(1)}, 73 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), "field1": int32(2)}, 74 }, 75 t: reflect.TypeOf(docWithObjectID{}), 76 want: []any{ 77 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), Field1: 0}, 78 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), Field1: 1}, 79 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), Field1: 2}, 80 }, 81 }, 82 { 83 name: "Read documents from MongoDB with id of type string", 84 input: []any{ 85 bson.M{"_id": "id01", "field1": int32(0)}, 86 bson.M{"_id": "id02", "field1": int32(1)}, 87 bson.M{"_id": "id03", "field1": int32(2)}, 88 }, 89 t: reflect.TypeOf(docWithStringID{}), 90 want: []any{ 91 docWithStringID{ID: "id01", Field1: 0}, 92 docWithStringID{ID: "id02", Field1: 1}, 93 docWithStringID{ID: "id03", Field1: 2}, 94 }, 95 }, 96 { 97 name: "Read documents from MongoDB where filter matches", 98 input: []any{ 99 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), "field1": int32(0)}, 100 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), "field1": int32(1)}, 101 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), "field1": int32(2)}, 102 }, 103 t: reflect.TypeOf(docWithObjectID{}), 104 options: []mongodbio.ReadOptionFn{ 105 mongodbio.WithReadFilter(bson.M{"field1": bson.M{"$gt": 0}}), 106 }, 107 want: []any{ 108 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), Field1: 1}, 109 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), Field1: 2}, 110 }, 111 }, 112 { 113 name: "Read documents from MongoDB with bucketAuto aggregation", 114 input: []any{ 115 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), "field1": int32(0)}, 116 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), "field1": int32(1)}, 117 bson.M{"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), "field1": int32(2)}, 118 }, 119 t: reflect.TypeOf(docWithObjectID{}), 120 options: []mongodbio.ReadOptionFn{ 121 mongodbio.WithReadBucketAuto(true), 122 }, 123 want: []any{ 124 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), Field1: 0}, 125 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), Field1: 1}, 126 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), Field1: 2}, 127 }, 128 }, 129 } 130 for _, tt := range tests { 131 t.Run(tt.name, func(t *testing.T) { 132 database := "db" 133 collection := "coll" 134 135 client := newClient(ctx, t, uri) 136 mongoCollection := client.Database(database).Collection(collection) 137 138 t.Cleanup(func() { 139 dropCollection(ctx, t, mongoCollection) 140 }) 141 142 writeDocuments(ctx, t, mongoCollection, tt.input) 143 144 p, s := beam.NewPipelineWithRoot() 145 146 got := mongodbio.Read(s, uri, database, collection, tt.t, tt.options...) 147 148 passert.Equals(s, got, tt.want...) 149 ptest.RunAndValidate(t, p) 150 }) 151 } 152 } 153 154 func TestMongoDBIO_Write(t *testing.T) { 155 integration.CheckFilters(t) 156 157 ctx := context.Background() 158 port := setUpTestContainer(ctx, t) 159 uri := fmt.Sprintf("mongodb://%s:%s", "localhost", port) 160 161 tests := []struct { 162 name string 163 input []any 164 options []mongodbio.WriteOptionFn 165 wantIDs []any 166 wantDocs []bson.M 167 }{ 168 { 169 name: "Write documents to MongoDB with id of type primitive.ObjectID", 170 input: []any{ 171 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), Field1: 0}, 172 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), Field1: 1}, 173 docWithObjectID{ID: objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), Field1: 2}, 174 }, 175 wantIDs: []any{ 176 objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), 177 objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), 178 objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), 179 }, 180 wantDocs: []bson.M{ 181 {"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28620"), "field1": int32(0)}, 182 {"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28621"), "field1": int32(1)}, 183 {"_id": objectIDFromHex(t, "61cf9980dd2d24dc5cf28622"), "field1": int32(2)}, 184 }, 185 }, 186 { 187 name: "Write documents to MongoDB with id of type string", 188 input: []any{ 189 docWithStringID{ID: "id01", Field1: 0}, 190 docWithStringID{ID: "id02", Field1: 1}, 191 docWithStringID{ID: "id03", Field1: 2}, 192 }, 193 wantIDs: []any{ 194 "id01", 195 "id02", 196 "id03", 197 }, 198 wantDocs: []bson.M{ 199 {"_id": "id01", "field1": int32(0)}, 200 {"_id": "id02", "field1": int32(1)}, 201 {"_id": "id03", "field1": int32(2)}, 202 }, 203 }, 204 } 205 for _, tt := range tests { 206 t.Run(tt.name, func(t *testing.T) { 207 database := "db" 208 collection := "coll" 209 210 client := newClient(ctx, t, uri) 211 mongoCollection := client.Database(database).Collection(collection) 212 213 t.Cleanup(func() { 214 dropCollection(ctx, t, mongoCollection) 215 }) 216 217 p, s := beam.NewPipelineWithRoot() 218 219 col := beam.CreateList(s, tt.input) 220 gotIDs := mongodbio.Write(s, uri, database, collection, col, tt.options...) 221 222 passert.Equals(s, gotIDs, tt.wantIDs...) 223 ptest.RunAndValidate(t, p) 224 225 if gotDocs := readDocuments(ctx, t, mongoCollection); !cmp.Equal(gotDocs, tt.wantDocs) { 226 t.Errorf("readDocuments() = %v, want %v", gotDocs, tt.wantDocs) 227 } 228 }) 229 } 230 } 231 232 func TestMain(m *testing.M) { 233 flag.Parse() 234 beam.Init() 235 236 ptest.MainRet(m) 237 }