TestPreparedStmtConcurrentClose test calling close and executing SQL concurrently this test making sure that the gorm would not get a Segmentation Fault, and the only error cause by this is using a closed Stmt
(t *testing.T)
| 235 | // TestPreparedStmtConcurrentClose test calling close and executing SQL concurrently |
| 236 | // this test making sure that the gorm would not get a Segmentation Fault, and the only error cause by this is using a closed Stmt |
| 237 | func TestPreparedStmtConcurrentClose(t *testing.T) { |
| 238 | name := "prepared_stmt_concurrent_close" |
| 239 | user := *GetUser(name, Config{}) |
| 240 | createTx := DB.Session(&gorm.Session{}).Create(&user) |
| 241 | if createTx.Error != nil { |
| 242 | t.Fatalf("failed to prepare record due to %s, test cannot be continue", createTx.Error) |
| 243 | } |
| 244 | |
| 245 | // create a new connection to keep away from other tests |
| 246 | tx, err := OpenTestConnection(&gorm.Config{PrepareStmt: true}) |
| 247 | if err != nil { |
| 248 | t.Fatalf("failed to open test connection due to %s", err) |
| 249 | } |
| 250 | pdb, ok := tx.ConnPool.(*gorm.PreparedStmtDB) |
| 251 | if !ok { |
| 252 | t.Fatalf("should assign PreparedStatement Manager back to database when using PrepareStmt mode") |
| 253 | } |
| 254 | |
| 255 | loopCount := 100 |
| 256 | var wg sync.WaitGroup |
| 257 | var unexpectedError bool |
| 258 | writerFinish := make(chan struct{}) |
| 259 | |
| 260 | wg.Add(1) |
| 261 | go func(id uint) { |
| 262 | defer wg.Done() |
| 263 | defer close(writerFinish) |
| 264 | |
| 265 | for j := 0; j < loopCount; j++ { |
| 266 | var tmp User |
| 267 | err := tx.Session(&gorm.Session{}).First(&tmp, id).Error |
| 268 | if err == nil || isUsingClosedConnError(err) { |
| 269 | continue |
| 270 | } |
| 271 | t.Errorf("failed to read user of id %d due to %s, there should not be error", id, err) |
| 272 | unexpectedError = true |
| 273 | break |
| 274 | } |
| 275 | }(user.ID) |
| 276 | |
| 277 | wg.Add(1) |
| 278 | go func() { |
| 279 | defer wg.Done() |
| 280 | <-writerFinish |
| 281 | pdb.Close() |
| 282 | }() |
| 283 | |
| 284 | wg.Wait() |
| 285 | |
| 286 | if unexpectedError { |
| 287 | t.Fatalf("should is a unexpected error") |
| 288 | } |
| 289 | } |
nothing calls this directly
no test coverage detected