github.com/tuhaihe/gpbackup@v1.0.3/integration/metadata_globals_create_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "regexp" 6 7 "github.com/tuhaihe/gp-common-go-libs/structmatcher" 8 "github.com/tuhaihe/gp-common-go-libs/testhelper" 9 "github.com/tuhaihe/gpbackup/backup" 10 "github.com/tuhaihe/gpbackup/testutils" 11 12 . "github.com/onsi/ginkgo/v2" 13 . "github.com/onsi/gomega" 14 . "github.com/onsi/gomega/gbytes" 15 ) 16 17 var _ = Describe("backup integration create statement tests", func() { 18 BeforeEach(func() { 19 tocfile, backupfile = testutils.InitializeTestTOC(buffer, "predata") 20 }) 21 Describe("PrintCreateDatabaseStatement", func() { 22 emptyDB := backup.Database{} 23 emptyMetadataMap := backup.MetadataMap{} 24 BeforeEach(func() { 25 connectionPool.DBName = "create_test_db" 26 }) 27 AfterEach(func() { 28 connectionPool.DBName = "testdb" 29 }) 30 It("creates a basic database", func() { 31 db := backup.Database{Oid: 1, Name: "create_test_db", Tablespace: "pg_default", Encoding: "UTF8"} 32 backup.PrintCreateDatabaseStatement(backupfile, tocfile, emptyDB, db, emptyMetadataMap) 33 34 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 35 defer testhelper.AssertQueryRuns(connectionPool, "DROP DATABASE create_test_db") 36 37 resultDB := backup.GetDatabaseInfo(connectionPool) 38 structmatcher.ExpectStructsToMatchExcluding(&db, &resultDB, "Oid", "Collate", "CType") 39 }) 40 It("creates a database with properties the same as defaults", func() { 41 defaultDB := backup.GetDefaultDatabaseEncodingInfo(connectionPool) 42 var db backup.Database 43 db = backup.Database{Oid: 1, Name: "create_test_db", Tablespace: "pg_default", Encoding: "UTF8", Collate: defaultDB.Collate, CType: defaultDB.Collate} 44 45 backup.PrintCreateDatabaseStatement(backupfile, tocfile, defaultDB, db, emptyMetadataMap) 46 47 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 48 defer testhelper.AssertQueryRuns(connectionPool, "DROP DATABASE create_test_db") 49 50 resultDB := backup.GetDatabaseInfo(connectionPool) 51 structmatcher.ExpectStructsToMatchExcluding(&db, &resultDB, "Oid") 52 }) 53 It("creates a database with all properties", func() { 54 var db backup.Database 55 if false { 56 db = backup.Database{Oid: 1, Name: "create_test_db", Tablespace: "pg_default", Encoding: "UTF8", Collate: "", CType: ""} 57 } else { 58 db = backup.Database{Oid: 1, Name: "create_test_db", Tablespace: "pg_default", Encoding: "UTF8", Collate: "en_US.utf-8", CType: "en_US.utf-8"} 59 } 60 61 backup.PrintCreateDatabaseStatement(backupfile, tocfile, emptyDB, db, emptyMetadataMap) 62 63 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 64 defer testhelper.AssertQueryRuns(connectionPool, "DROP DATABASE create_test_db") 65 66 resultDB := backup.GetDatabaseInfo(connectionPool) 67 structmatcher.ExpectStructsToMatchExcluding(&db, &resultDB, "Oid") 68 }) 69 }) 70 Describe("PrintDatabaseGUCs", func() { 71 It("creates database GUCs with correct quoting", func() { 72 enableNestLoopGUC := "SET enable_nestloop TO 'true'" 73 searchPathGUC := "SET search_path TO pg_catalog, public" 74 defaultStorageGUC := "SET gp_default_storage_options TO 'appendonly=true, compresslevel=6, orientation=row, compresstype=none'" 75 if true { 76 defaultStorageGUC = "SET gp_default_storage_options TO 'compresslevel=6, compresstype=none'" 77 } 78 79 gucs := []string{enableNestLoopGUC, searchPathGUC, defaultStorageGUC} 80 81 backup.PrintDatabaseGUCs(backupfile, tocfile, gucs, "testdb") 82 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 83 defer testhelper.AssertQueryRuns(connectionPool, "ALTER DATABASE testdb RESET enable_nestloop") 84 defer testhelper.AssertQueryRuns(connectionPool, "ALTER DATABASE testdb RESET search_path") 85 defer testhelper.AssertQueryRuns(connectionPool, "ALTER DATABASE testdb RESET gp_default_storage_options") 86 resultGUCs := backup.GetDatabaseGUCs(connectionPool) 87 Expect(resultGUCs).To(Equal(gucs)) 88 }) 89 }) 90 Describe("PrintCreateResourceQueueStatements", func() { 91 It("creates a basic resource queue with a comment", func() { 92 basicQueue := backup.ResourceQueue{Oid: 1, Name: `"basicQueue"`, ActiveStatements: -1, MaxCost: "32.80", CostOvercommit: false, MinCost: "0.00", Priority: "medium", MemoryLimit: "-1"} 93 resQueueMetadataMap := testutils.DefaultMetadataMap("RESOURCE QUEUE", false, false, true, false) 94 resQueueMetadata := resQueueMetadataMap[basicQueue.GetUniqueID()] 95 96 backup.PrintCreateResourceQueueStatements(backupfile, tocfile, []backup.ResourceQueue{basicQueue}, resQueueMetadataMap) 97 98 // CREATE RESOURCE QUEUE statements can not be part of a multi-command statement, so 99 // feed the CREATE RESOURCE QUEUE and COMMENT ON statements separately. 100 hunks := regexp.MustCompile(";\n\n").Split(buffer.String(), 2) 101 testhelper.AssertQueryRuns(connectionPool, hunks[0]) 102 defer testhelper.AssertQueryRuns(connectionPool, `DROP RESOURCE QUEUE "basicQueue"`) 103 testhelper.AssertQueryRuns(connectionPool, hunks[1]) 104 105 resultResourceQueues := backup.GetResourceQueues(connectionPool) 106 resQueueUniqueID := testutils.UniqueIDFromObjectName(connectionPool, "", "basicQueue", backup.TYPE_RESOURCEQUEUE) 107 resultMetadataMap := backup.GetCommentsForObjectType(connectionPool, backup.TYPE_RESOURCEQUEUE) 108 resultMetadata := resultMetadataMap[resQueueUniqueID] 109 structmatcher.ExpectStructsToMatch(&resultMetadata, &resQueueMetadata) 110 111 for _, resultQueue := range resultResourceQueues { 112 if resultQueue.Name == `"basicQueue"` { 113 structmatcher.ExpectStructsToMatchExcluding(&basicQueue, &resultQueue, "Oid") 114 return 115 } 116 } 117 }) 118 It("creates a resource queue with all attributes", func() { 119 everythingQueue := backup.ResourceQueue{Oid: 1, Name: `"everythingQueue"`, ActiveStatements: 7, MaxCost: "32.80", CostOvercommit: true, MinCost: "22.80", Priority: "low", MemoryLimit: "2GB"} 120 emptyMetadataMap := map[backup.UniqueID]backup.ObjectMetadata{} 121 122 backup.PrintCreateResourceQueueStatements(backupfile, tocfile, []backup.ResourceQueue{everythingQueue}, emptyMetadataMap) 123 124 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 125 defer testhelper.AssertQueryRuns(connectionPool, `DROP RESOURCE QUEUE "everythingQueue"`) 126 127 resultResourceQueues := backup.GetResourceQueues(connectionPool) 128 129 for _, resultQueue := range resultResourceQueues { 130 if resultQueue.Name == `"everythingQueue"` { 131 structmatcher.ExpectStructsToMatchExcluding(&everythingQueue, &resultQueue, "Oid") 132 return 133 } 134 } 135 Fail("Could not find everythingQueue") 136 }) 137 }) 138 Describe("PrintCreateResourceGroupStatements", func() { 139 BeforeEach(func() { 140 testutils.SkipIfBefore5(connectionPool) 141 }) 142 It("creates a basic resource group", func() { 143 someGroup := backup.ResourceGroup{Oid: 1, Name: "some_group", CPURateLimit: "10", MemoryLimit: "20", Concurrency: "15", MemorySharedQuota: "25", MemorySpillRatio: "30", MemoryAuditor: "0", Cpuset: "-1"} 144 emptyMetadataMap := map[backup.UniqueID]backup.ObjectMetadata{} 145 146 backup.PrintCreateResourceGroupStatements(backupfile, tocfile, []backup.ResourceGroup{someGroup}, emptyMetadataMap) 147 148 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 149 defer testhelper.AssertQueryRuns(connectionPool, `DROP RESOURCE GROUP some_group`) 150 151 resultResourceGroups := backup.GetResourceGroups(connectionPool) 152 153 for _, resultGroup := range resultResourceGroups { 154 if resultGroup.Name == "some_group" { 155 structmatcher.ExpectStructsToMatchExcluding(&someGroup, &resultGroup, "Oid") 156 return 157 } 158 } 159 Fail("Could not find some_group") 160 }) 161 It("creates a resource group with defaults", func() { 162 expectedDefaults := backup.ResourceGroup{Oid: 1, Name: "some_group", CPURateLimit: "10", MemoryLimit: "20", Concurrency: concurrencyDefault, MemorySharedQuota: memSharedDefault, MemorySpillRatio: memSpillDefault, MemoryAuditor: memAuditDefault, Cpuset: cpuSetDefault} 163 164 testhelper.AssertQueryRuns(connectionPool, "CREATE RESOURCE GROUP some_group WITH (CPU_RATE_LIMIT=10, MEMORY_LIMIT=20);") 165 defer testhelper.AssertQueryRuns(connectionPool, `DROP RESOURCE GROUP some_group`) 166 167 resultResourceGroups := backup.GetResourceGroups(connectionPool) 168 169 for _, resultGroup := range resultResourceGroups { 170 if resultGroup.Name == "some_group" { 171 structmatcher.ExpectStructsToMatchExcluding(&expectedDefaults, &resultGroup, "Oid") 172 return 173 } 174 } 175 Fail("Could not find some_group") 176 }) 177 It("creates a resource group using old format for MemorySpillRatio", func() { 178 // temporarily special case for 5x resource groups #temp5xResGroup 179 if false { 180 Skip("Test only applicable to GPDB 5.20 and above") 181 } 182 expectedDefaults := backup.ResourceGroup{Oid: 1, Name: "some_group", CPURateLimit: "10", MemoryLimit: "20", Concurrency: concurrencyDefault, MemorySharedQuota: memSharedDefault, MemorySpillRatio: "19", MemoryAuditor: memAuditDefault, Cpuset: cpuSetDefault} 183 184 testhelper.AssertQueryRuns(connectionPool, "CREATE RESOURCE GROUP some_group WITH (CPU_RATE_LIMIT=10, MEMORY_LIMIT=20, MEMORY_SPILL_RATIO=19);") 185 defer testhelper.AssertQueryRuns(connectionPool, `DROP RESOURCE GROUP some_group`) 186 187 resultResourceGroups := backup.GetResourceGroups(connectionPool) 188 189 for _, resultGroup := range resultResourceGroups { 190 if resultGroup.Name == "some_group" { 191 structmatcher.ExpectStructsToMatchExcluding(&expectedDefaults, &resultGroup, "Oid") 192 return 193 } 194 } 195 Fail("Could not find some_group") 196 }) 197 It("alters a default resource group", func() { 198 defaultGroup := backup.ResourceGroup{Oid: 1, Name: "default_group", CPURateLimit: "10", MemoryLimit: "20", Concurrency: "15", MemorySharedQuota: "25", MemorySpillRatio: "30", MemoryAuditor: "0", Cpuset: "-1"} 199 emptyMetadataMap := map[backup.UniqueID]backup.ObjectMetadata{} 200 201 backup.PrintCreateResourceGroupStatements(backupfile, tocfile, []backup.ResourceGroup{defaultGroup}, emptyMetadataMap) 202 203 hunks := regexp.MustCompile(";\n\n").Split(buffer.String(), 5) 204 for i := 0; i < 5; i++ { 205 testhelper.AssertQueryRuns(connectionPool, hunks[i]) 206 } 207 resultResourceGroups := backup.GetResourceGroups(connectionPool) 208 209 for _, resultGroup := range resultResourceGroups { 210 if resultGroup.Name == "default_group" { 211 structmatcher.ExpectStructsToMatchExcluding(&defaultGroup, &resultGroup, "Oid") 212 return 213 } 214 } 215 Fail("Could not find default_group") 216 }) 217 }) 218 Describe("PrintCreateRoleStatements", func() { 219 var role1 backup.Role 220 BeforeEach(func() { 221 role1 = backup.Role{ 222 Oid: 1, 223 Name: "role1", 224 Super: true, 225 Inherit: false, 226 CreateRole: false, 227 CreateDB: false, 228 CanLogin: false, 229 ConnectionLimit: -1, 230 Password: "", 231 ValidUntil: "", 232 ResQueue: "pg_default", 233 ResGroup: "default_group", 234 Createrexthttp: false, 235 Createrextgpfd: false, 236 Createwextgpfd: false, 237 Createrexthdfs: false, 238 Createwexthdfs: false, 239 TimeConstraints: nil, 240 } 241 }) 242 emptyMetadataMap := backup.MetadataMap{} 243 It("creates a basic role", func() { 244 if false { 245 role1.ResGroup = "" 246 } 247 248 backup.PrintCreateRoleStatements(backupfile, tocfile, []backup.Role{role1}, emptyMetadataMap) 249 250 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 251 defer testhelper.AssertQueryRuns(connectionPool, `DROP ROLE "role1"`) 252 role1.Oid = testutils.OidFromObjectName(connectionPool, "", "role1", backup.TYPE_ROLE) 253 254 resultRoles := backup.GetRoles(connectionPool) 255 for _, role := range resultRoles { 256 if role.Name == "role1" { 257 structmatcher.ExpectStructsToMatch(&role1, role) 258 return 259 } 260 } 261 Fail("Role 'role1' was not found") 262 }) 263 It("creates a role with all attributes", func() { 264 role1 := backup.Role{ 265 Oid: 1, 266 Name: "role1", 267 Super: false, 268 Inherit: true, 269 CreateRole: true, 270 CreateDB: true, 271 CanLogin: true, 272 ConnectionLimit: 4, 273 Password: "md5a8b2c77dfeba4705f29c094592eb3369", 274 ValidUntil: "2099-01-01 08:00:00-00", 275 ResQueue: "pg_default", 276 ResGroup: "", 277 Createrexthttp: true, 278 Createrextgpfd: true, 279 Createwextgpfd: true, 280 Createrexthdfs: true, 281 Createwexthdfs: true, 282 TimeConstraints: []backup.TimeConstraint{ 283 { 284 Oid: 0, 285 StartDay: 0, 286 StartTime: "13:30:00", 287 EndDay: 3, 288 EndTime: "14:30:00", 289 }, { 290 Oid: 0, 291 StartDay: 5, 292 StartTime: "00:00:00", 293 EndDay: 5, 294 EndTime: "24:00:00", 295 }, 296 }, 297 } 298 if true { 299 role1.ResGroup = "default_group" 300 } 301 if true { 302 role1.Createrexthdfs = false 303 role1.Createwexthdfs = false 304 } 305 metadataMap := testutils.DefaultMetadataMap("ROLE", false, false, true, includeSecurityLabels) 306 307 backup.PrintCreateRoleStatements(backupfile, tocfile, []backup.Role{role1}, metadataMap) 308 309 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 310 defer testhelper.AssertQueryRuns(connectionPool, `DROP ROLE "role1"`) 311 role1.Oid = testutils.OidFromObjectName(connectionPool, "", "role1", backup.TYPE_ROLE) 312 313 resultRoles := backup.GetRoles(connectionPool) 314 for _, role := range resultRoles { 315 if role.Name == "role1" { 316 structmatcher.ExpectStructsToMatchExcluding(&role1, role, "TimeConstraints.Oid") 317 return 318 } 319 } 320 Fail("Role 'role1' was not found") 321 }) 322 It("creates a role with replication", func() { 323 testutils.SkipIfBefore6(connectionPool) 324 325 role1.Replication = true 326 backup.PrintCreateRoleStatements(backupfile, tocfile, []backup.Role{role1}, emptyMetadataMap) 327 328 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 329 defer testhelper.AssertQueryRuns(connectionPool, `DROP ROLE "role1"`) 330 role1.Oid = testutils.OidFromObjectName(connectionPool, "", "role1", backup.TYPE_ROLE) 331 332 resultRoles := backup.GetRoles(connectionPool) 333 for _, role := range resultRoles { 334 if role.Name == "role1" { 335 structmatcher.ExpectStructsToMatch(&role1, role) 336 return 337 } 338 } 339 Fail("Role 'role1' was not found") 340 }) 341 }) 342 Describe("PrintRoleMembershipStatements", func() { 343 BeforeEach(func() { 344 testhelper.AssertQueryRuns(connectionPool, `CREATE ROLE usergroup`) 345 testhelper.AssertQueryRuns(connectionPool, `CREATE ROLE testuser`) 346 }) 347 AfterEach(func() { 348 defer testhelper.AssertQueryRuns(connectionPool, `DROP ROLE usergroup`) 349 defer testhelper.AssertQueryRuns(connectionPool, `DROP ROLE testuser`) 350 }) 351 It("grants a role without ADMIN OPTION", func() { 352 numRoleMembers := len(backup.GetRoleMembers(connectionPool)) 353 expectedRoleMember := backup.RoleMember{Role: "usergroup", Member: "testuser", Grantor: "testrole", IsAdmin: false} 354 backup.PrintRoleMembershipStatements(backupfile, tocfile, []backup.RoleMember{expectedRoleMember}) 355 356 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 357 358 resultRoleMembers := backup.GetRoleMembers(connectionPool) 359 Expect(resultRoleMembers).To(HaveLen(numRoleMembers + 1)) 360 for _, roleMember := range resultRoleMembers { 361 if roleMember.Role == "usergroup" { 362 structmatcher.ExpectStructsToMatch(&expectedRoleMember, &roleMember) 363 return 364 } 365 } 366 Fail("Role 'testuser' is not a member of role 'usergroup'") 367 }) 368 It("grants a role WITH ADMIN OPTION", func() { 369 numRoleMembers := len(backup.GetRoleMembers(connectionPool)) 370 expectedRoleMember := backup.RoleMember{Role: "usergroup", Member: "testuser", Grantor: "testrole", IsAdmin: true} 371 backup.PrintRoleMembershipStatements(backupfile, tocfile, []backup.RoleMember{expectedRoleMember}) 372 373 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 374 375 resultRoleMembers := backup.GetRoleMembers(connectionPool) 376 Expect(resultRoleMembers).To(HaveLen(numRoleMembers + 1)) 377 for _, roleMember := range resultRoleMembers { 378 if roleMember.Role == "usergroup" { 379 structmatcher.ExpectStructsToMatch(&expectedRoleMember, &roleMember) 380 return 381 } 382 } 383 Fail("Role 'testuser' is not a member of role 'usergroup'") 384 }) 385 }) 386 Describe("PrintRoleGUCStatements", func() { 387 BeforeEach(func() { 388 testhelper.AssertQueryRuns(connectionPool, `CREATE ROLE testuser`) 389 }) 390 AfterEach(func() { 391 testhelper.AssertQueryRuns(connectionPool, `DROP ROLE testuser`) 392 }) 393 It("Sets GUCs for a particular role", func() { 394 defaultStorageOptionsString := "appendonly=true, compresslevel=6, orientation=row, compresstype=none" 395 if true { 396 defaultStorageOptionsString = "compresslevel=6, compresstype=none" 397 } 398 399 roleConfigMap := map[string][]backup.RoleGUC{ 400 "testuser": { 401 {RoleName: "testuser", Config: fmt.Sprintf("SET gp_default_storage_options TO '%s'", defaultStorageOptionsString)}, 402 {RoleName: "testuser", Config: "SET search_path TO public"}}, 403 } 404 405 backup.PrintRoleGUCStatements(backupfile, tocfile, roleConfigMap) 406 407 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 408 409 resultGUCs := backup.GetRoleGUCs(connectionPool) 410 Expect(resultGUCs["testuser"]).To(ConsistOf(roleConfigMap["testuser"])) 411 }) 412 It("Sets GUCs for a role in a particular database", func() { 413 testutils.SkipIfBefore6(connectionPool) 414 415 defaultStorageOptionsString := "appendonly=true, compresslevel=6, orientation=row, compresstype=none" 416 if true { 417 defaultStorageOptionsString = "compresslevel=6, compresstype=none" 418 } 419 420 roleConfigMap := map[string][]backup.RoleGUC{ 421 "testuser": { 422 {RoleName: "testuser", DbName: "testdb", Config: fmt.Sprintf("SET gp_default_storage_options TO '%s'", defaultStorageOptionsString)}, 423 {RoleName: "testuser", DbName: "testdb", Config: "SET search_path TO public"}}, 424 } 425 426 backup.PrintRoleGUCStatements(backupfile, tocfile, roleConfigMap) 427 428 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 429 430 resultGUCs := backup.GetRoleGUCs(connectionPool) 431 Expect(resultGUCs["testuser"]).To(ConsistOf(roleConfigMap["testuser"])) 432 }) 433 }) 434 Describe("PrintCreateTablespaceStatements", func() { 435 var expectedTablespace backup.Tablespace 436 BeforeEach(func() { 437 if true { 438 expectedTablespace = backup.Tablespace{Oid: 1, Tablespace: "test_tablespace", FileLocation: "'/tmp/test_dir'", SegmentLocations: []string{}} 439 } else { 440 expectedTablespace = backup.Tablespace{Oid: 1, Tablespace: "test_tablespace", FileLocation: "test_dir"} 441 } 442 }) 443 It("creates a basic tablespace", func() { 444 numTablespaces := len(backup.GetTablespaces(connectionPool)) 445 emptyMetadataMap := backup.MetadataMap{} 446 backup.PrintCreateTablespaceStatements(backupfile, tocfile, []backup.Tablespace{expectedTablespace}, emptyMetadataMap) 447 448 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 449 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLESPACE test_tablespace") 450 451 resultTablespaces := backup.GetTablespaces(connectionPool) 452 Expect(resultTablespaces).To(HaveLen(numTablespaces + 1)) 453 for _, tablespace := range resultTablespaces { 454 if tablespace.Tablespace == "test_tablespace" { 455 structmatcher.ExpectStructsToMatchExcluding(&expectedTablespace, &tablespace, "Oid") 456 return 457 } 458 } 459 Fail("Tablespace 'test_tablespace' was not created") 460 }) 461 It("creates a basic tablespace with different segment locations and options", func() { 462 testutils.SkipIfBefore6(connectionPool) 463 464 expectedTablespace = backup.Tablespace{ 465 Oid: 1, Tablespace: "test_tablespace", FileLocation: "'/tmp/test_dir'", 466 SegmentLocations: []string{"content0='/tmp/test_dir1'", "content1='/tmp/test_dir2'"}, 467 Options: "seq_page_cost=123", 468 } 469 numTablespaces := len(backup.GetTablespaces(connectionPool)) 470 emptyMetadataMap := backup.MetadataMap{} 471 backup.PrintCreateTablespaceStatements(backupfile, tocfile, []backup.Tablespace{expectedTablespace}, emptyMetadataMap) 472 473 gbuffer := BufferWithBytes([]byte(buffer.String())) 474 entries, _ := testutils.SliceBufferByEntries(tocfile.GlobalEntries, gbuffer) 475 create, setOptions := entries[0], entries[1] 476 testhelper.AssertQueryRuns(connectionPool, create) 477 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLESPACE test_tablespace") 478 testhelper.AssertQueryRuns(connectionPool, setOptions) 479 480 resultTablespaces := backup.GetTablespaces(connectionPool) 481 Expect(resultTablespaces).To(HaveLen(numTablespaces + 1)) 482 for _, tablespace := range resultTablespaces { 483 if tablespace.Tablespace == "test_tablespace" { 484 structmatcher.ExpectStructsToMatchExcluding(&expectedTablespace, &tablespace, "Oid") 485 return 486 } 487 } 488 Fail("Tablespace 'test_tablespace' was not created") 489 }) 490 It("creates a tablespace with permissions, an owner, security label, and a comment", func() { 491 numTablespaces := len(backup.GetTablespaces(connectionPool)) 492 tablespaceMetadataMap := testutils.DefaultMetadataMap("TABLESPACE", true, true, true, includeSecurityLabels) 493 tablespaceMetadata := tablespaceMetadataMap[expectedTablespace.GetUniqueID()] 494 backup.PrintCreateTablespaceStatements(backupfile, tocfile, []backup.Tablespace{expectedTablespace}, tablespaceMetadataMap) 495 496 if true { 497 /* 498 * In GPDB 6 and later, a CREATE TABLESPACE statement can't be run in a multi-command string 499 * with other statements, so we execute it separately from the metadata statements. 500 */ 501 gbuffer := BufferWithBytes([]byte(buffer.String())) 502 entries, _ := testutils.SliceBufferByEntries(tocfile.GlobalEntries, gbuffer) 503 for _, entry := range entries { 504 testhelper.AssertQueryRuns(connectionPool, entry) 505 } 506 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLESPACE test_tablespace") 507 } else { 508 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 509 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLESPACE test_tablespace") 510 } 511 512 resultTablespaces := backup.GetTablespaces(connectionPool) 513 resultMetadataMap := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_TABLESPACE) 514 Expect(resultTablespaces).To(HaveLen(numTablespaces + 1)) 515 for _, tablespace := range resultTablespaces { 516 if tablespace.Tablespace == "test_tablespace" { 517 resultMetadata := resultMetadataMap[tablespace.GetUniqueID()] 518 structmatcher.ExpectStructsToMatchExcluding(&tablespaceMetadata, &resultMetadata, "Oid") 519 structmatcher.ExpectStructsToMatchExcluding(&expectedTablespace, &tablespace, "Oid") 520 return 521 } 522 } 523 Fail("Tablespace 'test_tablespace' was not created") 524 }) 525 }) 526 })