用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

191 lines
7.1 KiB

/*
Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
// First include (the generated) my_config.h, to get correct platform defines.
#include "my_config.h"
#include <gtest/gtest.h>
#include <sys/types.h>
#include "lex_string.h"
#include "sql/opt_costconstantcache.h"
#include "sql/opt_costmodel.h"
#include "unittest/gunit/fake_table.h"
#include "unittest/gunit/test_utils.h"
namespace costmodel_unittest {
using my_testing::Server_initializer;
class CostModelTest : public ::testing::Test {
protected:
virtual void SetUp() {
// Add a storage engine to the hton2plugin array.
// This is needed for the cost model to add cost constants
// for the storage engine
LEX_CSTRING engine_name = {STRING_WITH_LEN("InnoDB")};
insert_hton2plugin(0, new st_plugin_int())->name = engine_name;
initializer.SetUp();
}
virtual void TearDown() {
initializer.TearDown();
delete remove_hton2plugin(0);
}
THD *thd() { return initializer.thd(); }
Server_initializer initializer;
};
/*
Tests for temporary tables that are not dependent on hard coded cost
constants.
*/
static void test_tmptable_cost(
const Cost_model_server *cm,
Cost_model_server::enum_tmptable_type tmp_table_type) {
const uint rows = 3;
// Cost of inserting and reading data in a temporary table
EXPECT_EQ(cm->tmptable_readwrite_cost(tmp_table_type, rows, rows),
rows * cm->tmptable_readwrite_cost(tmp_table_type, 1.0, 1.0));
}
/*
Test the Cost_model_server interface.
*/
TEST_F(CostModelTest, CostModelServer) {
const uint rows = 3;
// Create and initialize the server cost model
Cost_model_server cm;
cm.init();
// Create and initialize a cost constant object that will be used
// for verifying default values for cost constants
const Server_cost_constants default_server_cost;
// Test row evaluate cost
EXPECT_EQ(cm.row_evaluate_cost(1.0), default_server_cost.row_evaluate_cost());
EXPECT_EQ(cm.row_evaluate_cost(rows), rows * cm.row_evaluate_cost(1.0));
// Test key compare cost
EXPECT_EQ(cm.key_compare_cost(1.0), default_server_cost.key_compare_cost());
EXPECT_EQ(cm.key_compare_cost(rows), rows * cm.key_compare_cost(1.0));
// Cost of creating a tempoary table without inserting data into it
EXPECT_EQ(cm.tmptable_create_cost(Cost_model_server::MEMORY_TMPTABLE),
default_server_cost.memory_temptable_create_cost());
EXPECT_EQ(cm.tmptable_create_cost(Cost_model_server::DISK_TMPTABLE),
default_server_cost.disk_temptable_create_cost());
// Cost of inserting one row in a temporary table
EXPECT_EQ(
cm.tmptable_readwrite_cost(Cost_model_server::MEMORY_TMPTABLE, 1.0, 0.0),
default_server_cost.memory_temptable_row_cost());
EXPECT_EQ(
cm.tmptable_readwrite_cost(Cost_model_server::DISK_TMPTABLE, 1.0, 0.0),
default_server_cost.disk_temptable_row_cost());
// Cost of reading one row in a temporary table
EXPECT_EQ(
cm.tmptable_readwrite_cost(Cost_model_server::MEMORY_TMPTABLE, 0.0, 1.0),
default_server_cost.memory_temptable_row_cost());
EXPECT_EQ(
cm.tmptable_readwrite_cost(Cost_model_server::DISK_TMPTABLE, 0.0, 1.0),
default_server_cost.disk_temptable_row_cost());
// Tests for temporary tables that are independent of cost constants
test_tmptable_cost(&cm, Cost_model_server::MEMORY_TMPTABLE);
test_tmptable_cost(&cm, Cost_model_server::DISK_TMPTABLE);
}
/*
Test the Cost_model_table interface.
*/
TEST_F(CostModelTest, CostModelTable) {
const uint rows = 3;
const double blocks = 4.0;
const uint key = 0;
// A table is needed in order to initialize the table cost model
Fake_TABLE table(1, false);
// Create and initialize a cost model table object
Cost_model_server cost_model_server;
cost_model_server.init();
Cost_model_table cm;
cm.init(&cost_model_server, &table);
// Create and initialize a cost constant object that will be used
// for verifying default values for cost constants
const Server_cost_constants default_server_cost;
const SE_cost_constants default_engine_cost;
// Test row evaluate cost
EXPECT_EQ(cm.row_evaluate_cost(1.0), default_server_cost.row_evaluate_cost());
EXPECT_EQ(cm.row_evaluate_cost(rows), rows * cm.row_evaluate_cost(1.0));
// Test key compare cost
EXPECT_EQ(cm.key_compare_cost(1.0), default_server_cost.key_compare_cost());
EXPECT_EQ(cm.key_compare_cost(rows), rows * cm.key_compare_cost(1.0));
// Test io block read cost
EXPECT_EQ(cm.io_block_read_cost(1.0),
default_engine_cost.io_block_read_cost());
EXPECT_EQ(cm.io_block_read_cost(blocks), blocks * cm.io_block_read_cost(1.0));
// Test page_read_cost() with table in memory buffer
EXPECT_EQ(cm.page_read_cost(1.0),
default_engine_cost.memory_block_read_cost());
EXPECT_EQ(cm.page_read_cost(blocks), blocks * cm.page_read_cost(1.0));
// Test page_read_cost() with table data on disk
table.file->stats.table_in_mem_estimate = 0.0; // Table is on disk
EXPECT_EQ(cm.page_read_cost(1.0), default_engine_cost.io_block_read_cost());
EXPECT_EQ(cm.page_read_cost(blocks), blocks * cm.page_read_cost(1.0));
// Test page_read_cost_index() with index data in memory
table.key_info[key].set_in_memory_estimate(1.0); // Index is in memory
EXPECT_EQ(cm.page_read_cost_index(key, 1.0),
default_engine_cost.memory_block_read_cost());
EXPECT_EQ(cm.page_read_cost_index(key, blocks),
blocks * cm.page_read_cost_index(key, 1.0));
// Test page_read_oost_index() with index data on disk
table.key_info[key].set_in_memory_estimate(0.0); // Index is on disk
EXPECT_EQ(cm.page_read_cost_index(key, 1.0),
default_engine_cost.io_block_read_cost());
EXPECT_EQ(cm.page_read_cost_index(key, blocks),
blocks * cm.page_read_cost_index(key, 1.0));
// Test disk seek base cost
EXPECT_EQ(cm.disk_seek_base_cost(),
DISK_SEEK_BASE_COST * cm.io_block_read_cost(1.0));
// Test disk seek cost
EXPECT_GT(cm.disk_seek_cost(2.0), cm.disk_seek_cost(1.0));
}
} // namespace costmodel_unittest