Test teardown of a query while writes are in flight. This was based on a BufferedBlockMgr regression test for IMPALA-2252 where tear-down of the query's RuntimeStates raced with scratch writes. If write_error is true, force writes to hit errors.
| 1547 | /// query's RuntimeStates raced with scratch writes. If write_error is true, |
| 1548 | /// force writes to hit errors. |
| 1549 | void BufferPoolTest::TestQueryTeardown(bool write_error) { |
| 1550 | const int64_t TOTAL_BUFFERS = 20; |
| 1551 | const int CLIENT_BUFFERS = 10; |
| 1552 | const int64_t TOTAL_MEM = TOTAL_BUFFERS * TEST_BUFFER_LEN; |
| 1553 | const int64_t CLIENT_MEM = CLIENT_BUFFERS * TEST_BUFFER_LEN; |
| 1554 | |
| 1555 | // Set up a BufferPool in the TestEnv. |
| 1556 | test_env_.reset(new TestEnv()); |
| 1557 | test_env_->SetBufferPoolArgs(TEST_BUFFER_LEN, TOTAL_MEM); |
| 1558 | ASSERT_OK(test_env_->Init()); |
| 1559 | |
| 1560 | BufferPool* pool = test_env_->exec_env()->buffer_pool(); |
| 1561 | RuntimeState* state; |
| 1562 | ASSERT_OK(test_env_->CreateQueryState(0, nullptr, &state)); |
| 1563 | |
| 1564 | ClientHandle client; |
| 1565 | ASSERT_OK(pool->RegisterClient("test client", state->query_state()->file_group(), |
| 1566 | state->instance_buffer_reservation(), |
| 1567 | obj_pool_.Add(new MemTracker(-1, "", state->instance_mem_tracker())), CLIENT_MEM, |
| 1568 | NewProfile(), &client)); |
| 1569 | ASSERT_TRUE(client.IncreaseReservation(CLIENT_MEM)); |
| 1570 | |
| 1571 | vector<PageHandle> pages; |
| 1572 | CreatePages(pool, &client, TEST_BUFFER_LEN, CLIENT_BUFFERS, &pages); |
| 1573 | |
| 1574 | if (write_error) { |
| 1575 | UnpinAll(pool, &client, &pages); |
| 1576 | // Allocate more buffers to create memory pressure and force eviction of all the |
| 1577 | // unpinned pages. |
| 1578 | vector<BufferHandle> tmp_buffers; |
| 1579 | AllocateBuffers(pool, &client, TEST_BUFFER_LEN, CLIENT_BUFFERS, &tmp_buffers); |
| 1580 | string tmp_file_path = TmpFilePath(pages.data()); |
| 1581 | FreeBuffers(pool, &client, &tmp_buffers); |
| 1582 | |
| 1583 | ASSERT_OK(PinAll(pool, &client, &pages)); |
| 1584 | // Remove temporary file to force future writes to that file to fail. |
| 1585 | DisableBackingFile(tmp_file_path); |
| 1586 | } |
| 1587 | |
| 1588 | // Unpin will initiate writes. If we triggered a write error earlier, some writes may |
| 1589 | // go down the error path. |
| 1590 | UnpinAll(pool, &client, &pages); |
| 1591 | |
| 1592 | // Tear down the pages, client, and query in the correct order while writes are in |
| 1593 | // flight. |
| 1594 | DestroyAll(pool, &client, &pages); |
| 1595 | pool->DeregisterClient(&client); |
| 1596 | test_env_->TearDownQueries(); |
| 1597 | |
| 1598 | // All memory should be released from the query. |
| 1599 | EXPECT_EQ(0, test_env_->TotalQueryMemoryConsumption()); |
| 1600 | EXPECT_EQ(0, test_env_->exec_env()->buffer_reservation()->GetChildReservations()); |
| 1601 | } |
| 1602 | |
| 1603 | TEST_F(BufferPoolTest, QueryTeardown) { |
| 1604 | TestQueryTeardown(false); |
nothing calls this directly
no test coverage detected