github.com/google/trillian-examples@v0.0.0-20240520080811-0d40d35cef0e/clone/internal/cloner/clone_test.go (about) 1 // Copyright 2021 Google LLC. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // clone contains the core engine for quickly downloading leaves and adding 16 // them to the database. 17 package cloner 18 19 import ( 20 "context" 21 "database/sql" 22 "fmt" 23 "testing" 24 25 "github.com/google/trillian-examples/clone/logdb" 26 _ "github.com/mattn/go-sqlite3" // Load drivers for sqlite3 27 ) 28 29 func TestClone(t *testing.T) { 30 for _, test := range []struct { 31 name string 32 first, treeSize uint64 33 workers, fetchBatchSize, writeBatchSize uint 34 }{ 35 { 36 name: "smallest batch", 37 first: 0, 38 treeSize: 10, 39 workers: 1, 40 fetchBatchSize: 1, 41 writeBatchSize: 1, 42 }, 43 { 44 name: "normal settings", 45 first: 0, 46 treeSize: 100, 47 workers: 4, 48 fetchBatchSize: 5, 49 writeBatchSize: 10, 50 }, 51 { 52 name: "oversized batches", 53 first: 0, 54 treeSize: 10, 55 workers: 10, 56 fetchBatchSize: 100, 57 writeBatchSize: 100, 58 }, 59 } { 60 t.Run(test.name, func(t *testing.T) { 61 db, close, err := newInMemoryDatabase() 62 if err != nil { 63 t.Fatalf("NewDatabase(): %v", err) 64 } 65 defer close() 66 67 cloner := New(test.workers, test.fetchBatchSize, test.writeBatchSize, db) 68 fetcher := func(start uint64, leaves [][]byte) (uint64, error) { 69 for i := range leaves { 70 leaves[i] = []byte(fmt.Sprintf("leaf %d", start+1)) 71 } 72 return uint64(len(leaves)), nil 73 } 74 if err := cloner.clone(context.Background(), test.treeSize, fetcher); err != nil { 75 t.Fatalf("Clone(): %v", err) 76 } 77 78 if head, err := db.Head(); err != nil { 79 t.Fatalf("Head(): %v", err) 80 } else if gotSize := head + 1; gotSize != int64(test.treeSize) { 81 t.Errorf("got tree size %d, want %d", gotSize, test.treeSize) 82 } 83 }) 84 } 85 } 86 87 func newInMemoryDatabase() (*logdb.Database, func(), error) { 88 sqlitedb, err := sql.Open("sqlite3", ":memory:") 89 if err != nil { 90 return nil, nil, fmt.Errorf("failed to open temporary in-memory DB: %v", err) 91 } 92 db, err := logdb.NewDatabaseDirect(sqlitedb) 93 return db, func() { _ = sqlitedb.Close }, err 94 }