github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/clusterintegrationtest/fakes_for_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 //go:build integrationTest 13 // +build integrationTest 14 15 package clusterintegrationtest 16 17 import ( 18 "context" 19 "encoding/json" 20 "fmt" 21 "io" 22 "net/http" 23 "net/http/httptest" 24 "net/url" 25 "path" 26 "sync" 27 "time" 28 29 "github.com/sirupsen/logrus/hooks/test" 30 "github.com/weaviate/weaviate/adapters/clients" 31 "github.com/weaviate/weaviate/adapters/handlers/rest/clusterapi" 32 "github.com/weaviate/weaviate/adapters/repos/db" 33 "github.com/weaviate/weaviate/entities/backup" 34 "github.com/weaviate/weaviate/entities/models" 35 "github.com/weaviate/weaviate/entities/modulecapabilities" 36 "github.com/weaviate/weaviate/entities/schema" 37 modstgfs "github.com/weaviate/weaviate/modules/backup-filesystem" 38 ubak "github.com/weaviate/weaviate/usecases/backup" 39 "github.com/weaviate/weaviate/usecases/sharding" 40 ) 41 42 type node struct { 43 name string 44 repo *db.DB 45 schemaManager *fakeSchemaManager 46 backupManager *ubak.Handler 47 scheduler *ubak.Scheduler 48 migrator *db.Migrator 49 hostname string 50 } 51 52 func (n *node) init(dirName string, shardStateRaw []byte, 53 allNodes *[]*node, 54 ) { 55 localDir := path.Join(dirName, n.name) 56 logger, _ := test.NewNullLogger() 57 58 nodeResolver := &nodeResolver{ 59 nodes: allNodes, 60 local: n.name, 61 } 62 63 shardState, err := sharding.StateFromJSON(shardStateRaw, nodeResolver) 64 if err != nil { 65 panic(err) 66 } 67 68 client := clients.NewRemoteIndex(&http.Client{}) 69 nodesClient := clients.NewRemoteNode(&http.Client{}) 70 replicaClient := clients.NewReplicationClient(&http.Client{}) 71 n.repo, err = db.New(logger, db.Config{ 72 MemtablesFlushDirtyAfter: 60, 73 RootPath: localDir, 74 QueryMaximumResults: 10000, 75 MaxImportGoroutinesFactor: 1, 76 }, client, nodeResolver, nodesClient, replicaClient, nil) 77 if err != nil { 78 panic(err) 79 } 80 n.schemaManager = &fakeSchemaManager{ 81 shardState: shardState, 82 schema: schema.Schema{Objects: &models.Schema{}}, 83 nodeResolver: nodeResolver, 84 } 85 86 n.repo.SetSchemaGetter(n.schemaManager) 87 err = n.repo.WaitForStartup(context.Background()) 88 if err != nil { 89 panic(err) 90 } 91 92 backendProvider := newFakeBackupBackendProvider(localDir) 93 n.backupManager = ubak.NewHandler( 94 logger, &fakeAuthorizer{}, n.schemaManager, n.repo, backendProvider) 95 96 backupClient := clients.NewClusterBackups(&http.Client{}) 97 n.scheduler = ubak.NewScheduler( 98 &fakeAuthorizer{}, backupClient, n.repo, backendProvider, nodeResolver, logger) 99 100 n.migrator = db.NewMigrator(n.repo, logger) 101 102 indices := clusterapi.NewIndices(sharding.NewRemoteIndexIncoming(n.repo), n.repo, clusterapi.NewNoopAuthHandler()) 103 mux := http.NewServeMux() 104 mux.Handle("/indices/", indices.Indices()) 105 106 backups := clusterapi.NewBackups(n.backupManager, clusterapi.NewNoopAuthHandler()) 107 mux.Handle("/backups/can-commit", backups.CanCommit()) 108 mux.Handle("/backups/commit", backups.Commit()) 109 mux.Handle("/backups/abort", backups.Abort()) 110 mux.Handle("/backups/status", backups.Status()) 111 112 srv := httptest.NewServer(mux) 113 u, err := url.Parse(srv.URL) 114 if err != nil { 115 panic(err) 116 } 117 n.hostname = u.Host 118 } 119 120 type fakeNodes struct { 121 nodes []string 122 } 123 124 func (f fakeNodes) Candidates() []string { 125 return f.nodes 126 } 127 128 func (f fakeNodes) LocalName() string { 129 return f.nodes[0] 130 } 131 132 type fakeSchemaManager struct { 133 schema schema.Schema 134 shardState *sharding.State 135 nodeResolver *nodeResolver 136 } 137 138 func (f *fakeSchemaManager) GetSchemaSkipAuth() schema.Schema { 139 return f.schema 140 } 141 142 func (f *fakeSchemaManager) CopyShardingState(class string) *sharding.State { 143 return f.shardState 144 } 145 146 func (f *fakeSchemaManager) ShardOwner(class, shard string) (string, error) { 147 ss := f.shardState 148 x, ok := ss.Physical[shard] 149 if !ok { 150 return "", fmt.Errorf("shard not found") 151 } 152 if len(x.BelongsToNodes) < 1 || x.BelongsToNodes[0] == "" { 153 return "", fmt.Errorf("owner node not found") 154 } 155 return ss.Physical[shard].BelongsToNodes[0], nil 156 } 157 158 func (f *fakeSchemaManager) ShardReplicas(class, shard string) ([]string, error) { 159 ss := f.shardState 160 x, ok := ss.Physical[shard] 161 if !ok { 162 return nil, fmt.Errorf("shard not found") 163 } 164 return x.BelongsToNodes, nil 165 } 166 167 func (f *fakeSchemaManager) TenantShard(class, tenant string) (string, string) { 168 return tenant, models.TenantActivityStatusHOT 169 } 170 171 func (f *fakeSchemaManager) ShardFromUUID(class string, uuid []byte) string { 172 ss := f.shardState 173 return ss.Shard("", string(uuid)) 174 } 175 176 func (f *fakeSchemaManager) RestoreClass(ctx context.Context, d *backup.ClassDescriptor, nodeMapping map[string]string) error { 177 return nil 178 } 179 180 func (f *fakeSchemaManager) Nodes() []string { 181 return []string{"NOT SET"} 182 } 183 184 func (f *fakeSchemaManager) NodeName() string { 185 return f.nodeResolver.local 186 } 187 188 func (f *fakeSchemaManager) ClusterHealthScore() int { 189 return 0 190 } 191 192 func (f *fakeSchemaManager) ResolveParentNodes(_ string, shard string, 193 ) (map[string]string, error) { 194 return nil, nil 195 } 196 197 type nodeResolver struct { 198 nodes *[]*node 199 local string 200 } 201 202 func (r nodeResolver) AllNames() []string { 203 xs := []string{} 204 for _, n := range *r.nodes { 205 xs = append(xs, n.name) 206 } 207 return xs 208 } 209 210 func (r nodeResolver) Candidates() []string { 211 return nil 212 } 213 214 func (r nodeResolver) LocalName() string { 215 return r.local 216 } 217 218 func (r nodeResolver) NodeCount() int { 219 return len(*r.nodes) 220 } 221 222 func (r nodeResolver) NodeHostname(nodeName string) (string, bool) { 223 for _, node := range *r.nodes { 224 if node.name == nodeName { 225 return node.hostname, true 226 } 227 } 228 229 return "", false 230 } 231 232 func newFakeBackupBackendProvider(backupsPath string) *fakeBackupBackendProvider { 233 return &fakeBackupBackendProvider{ 234 backupsPath: backupsPath, 235 } 236 } 237 238 type fakeBackupBackendProvider struct { 239 backupsPath string 240 } 241 242 func (f *fakeBackupBackendProvider) BackupBackend(name string) (modulecapabilities.BackupBackend, error) { 243 backend.setLocal(name == modstgfs.Name) 244 return backend, nil 245 } 246 247 type fakeBackupBackend struct { 248 sync.Mutex 249 backupsPath string 250 backupID string 251 counter int 252 isLocal bool 253 startedAt time.Time 254 } 255 256 func (f *fakeBackupBackend) HomeDir(backupID string) string { 257 f.Lock() 258 defer f.Unlock() 259 return f.backupsPath 260 } 261 262 func (f *fakeBackupBackend) GetObject(ctx context.Context, backupID, key string) ([]byte, error) { 263 f.Lock() 264 defer f.Unlock() 265 266 f.counter++ 267 268 if f.counter <= 2 { 269 return nil, backup.ErrNotFound{} 270 } 271 272 var resp interface{} 273 274 if key == ubak.GlobalBackupFile { 275 resp = f.successGlobalMeta() 276 } else { 277 resp = f.successLocalMeta() 278 } 279 280 b, _ := json.Marshal(resp) 281 return b, nil 282 } 283 284 func (f *fakeBackupBackend) WriteToFile(ctx context.Context, backupID, key, destPath string) error { 285 f.Lock() 286 defer f.Unlock() 287 return nil 288 } 289 290 func (f *fakeBackupBackend) Write(ctx context.Context, backupID, key string, r io.ReadCloser) (int64, error) { 291 f.Lock() 292 defer f.Unlock() 293 defer r.Close() 294 return 0, nil 295 } 296 297 func (f *fakeBackupBackend) Read(ctx context.Context, backupID, key string, w io.WriteCloser) (int64, error) { 298 f.Lock() 299 defer f.Unlock() 300 defer w.Close() 301 return 0, nil 302 } 303 304 func (f *fakeBackupBackend) SourceDataPath() string { 305 f.Lock() 306 defer f.Unlock() 307 return f.backupsPath 308 } 309 310 func (f *fakeBackupBackend) setLocal(v bool) { 311 f.Lock() 312 defer f.Unlock() 313 f.isLocal = v 314 } 315 316 func (f *fakeBackupBackend) IsExternal() bool { 317 f.Lock() 318 defer f.Unlock() 319 return !f.isLocal 320 } 321 322 func (f *fakeBackupBackend) Name() string { 323 return "fakeBackupBackend" 324 } 325 326 func (f *fakeBackupBackend) PutFile(ctx context.Context, backupID, key, srcPath string) error { 327 f.Lock() 328 defer f.Unlock() 329 return nil 330 } 331 332 func (f *fakeBackupBackend) PutObject(ctx context.Context, backupID, key string, byes []byte) error { 333 f.Lock() 334 defer f.Unlock() 335 return nil 336 } 337 338 func (f *fakeBackupBackend) Initialize(ctx context.Context, backupID string) error { 339 f.Lock() 340 defer f.Unlock() 341 return nil 342 } 343 344 func (f *fakeBackupBackend) successGlobalMeta() backup.DistributedBackupDescriptor { 345 return backup.DistributedBackupDescriptor{ 346 StartedAt: f.startedAt, 347 ID: f.backupID, 348 Nodes: map[string]*backup.NodeDescriptor{ 349 "node-0": { 350 Classes: []string{distributedClass}, 351 Status: "SUCCESS", 352 }, 353 }, 354 Status: "SUCCESS", 355 Version: ubak.Version, 356 ServerVersion: "x.x.x", 357 } 358 } 359 360 func (f *fakeBackupBackend) successLocalMeta() backup.BackupDescriptor { 361 return backup.BackupDescriptor{ 362 ID: f.backupID, 363 Status: "SUCCESS", 364 ServerVersion: "x.x.x", 365 Version: ubak.Version, 366 StartedAt: f.startedAt, 367 Classes: []backup.ClassDescriptor{ 368 { 369 Name: distributedClass, 370 Shards: []*backup.ShardDescriptor{ 371 { 372 Name: "123", 373 Node: "node-0", 374 Files: []string{"some-file.db"}, 375 DocIDCounter: []byte("1"), 376 DocIDCounterPath: ".", 377 Version: []byte("1"), 378 ShardVersionPath: ".", 379 PropLengthTracker: []byte("1"), 380 PropLengthTrackerPath: ".", 381 }, 382 }, 383 ShardingState: []byte("sharding state!"), 384 Schema: []byte("schema!"), 385 }, 386 }, 387 } 388 } 389 390 func (f *fakeBackupBackend) reset() { 391 f.counter = 0 392 } 393 394 type fakeAuthorizer struct{} 395 396 func (f *fakeAuthorizer) Authorize(_ *models.Principal, _, _ string) error { 397 return nil 398 }