1 /*
2 Copyright (c) 2014, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation,
22 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
23
24 // First include (the generated) my_config.h, to get correct platform defines.
25 #include "my_config.h"
26 #include <gtest/gtest.h>
27
28 #include "fake_key.h" // Fake_KEY
29 #include "key.h" // KEY
30
31 namespace recperkey_unittest {
32
33 /**
34 Test the API for setting and getting records per key values.
35 */
36
TEST(RecPerKeyTest,RecPerKeyAPI)37 TEST(RecPerKeyTest, RecPerKeyAPI)
38 {
39 const uint key_parts= 3;
40
41 Fake_KEY key(key_parts, false);
42
43 /*
44 Test that the rec_per_key values are default/unknown.
45 */
46 for (uint kp=0; kp < key_parts; kp++)
47 {
48 EXPECT_FALSE(key.has_records_per_key(kp));
49 EXPECT_EQ(key.records_per_key(kp), REC_PER_KEY_UNKNOWN);
50 }
51
52 /*
53 Test setting the values using the API
54 */
55
56 // Give one of the key parts a value
57 key.set_records_per_key(1, 2.0);
58
59 // Validate that only one of the key parts has gotten a value
60 EXPECT_FALSE(key.has_records_per_key(0));
61 EXPECT_TRUE(key.has_records_per_key(1));
62 EXPECT_FALSE(key.has_records_per_key(2));
63
64 EXPECT_EQ(key.records_per_key(0), REC_PER_KEY_UNKNOWN);
65 EXPECT_EQ(key.records_per_key(1), 2.0);
66 EXPECT_EQ(key.records_per_key(2), REC_PER_KEY_UNKNOWN);
67
68 // Reset the rec_per_key value to default/unkown
69 key.set_records_per_key(1, REC_PER_KEY_UNKNOWN);
70 EXPECT_FALSE(key.has_records_per_key(1));
71 EXPECT_EQ(key.records_per_key(1), REC_PER_KEY_UNKNOWN);
72 }
73
74
75 /**
76 Test the old integer based rec_per_key implementation used
77 together with the records per key API.
78 */
79
TEST(RecPerKeyTest,RecPerKey)80 TEST(RecPerKeyTest, RecPerKey)
81 {
82 const uint key_parts= 3;
83
84 Fake_KEY key(key_parts, false);
85
86 // Set values directly in the integer based rec_per_key array
87 key.rec_per_key[0]= 0; // default/unknown value
88 key.rec_per_key[1]= 1;
89 key.rec_per_key[2]= 2;
90
91 // Validate that this produces correct values using the API functions
92 EXPECT_FALSE(key.has_records_per_key(0));
93 EXPECT_EQ(key.records_per_key(0), REC_PER_KEY_UNKNOWN);
94 EXPECT_TRUE(key.has_records_per_key(1));
95 EXPECT_EQ(key.records_per_key(1), 1.0);
96 EXPECT_TRUE(key.has_records_per_key(2));
97 EXPECT_EQ(key.records_per_key(2), 2.0);
98
99 // Reset the values
100 key.rec_per_key[1]= 0;
101 key.rec_per_key[2]= 0;
102 EXPECT_FALSE(key.has_records_per_key(0));
103 EXPECT_EQ(key.records_per_key(0), REC_PER_KEY_UNKNOWN);
104 EXPECT_FALSE(key.has_records_per_key(1));
105 EXPECT_EQ(key.records_per_key(1), REC_PER_KEY_UNKNOWN);
106 EXPECT_FALSE(key.has_records_per_key(2));
107 EXPECT_EQ(key.records_per_key(2), REC_PER_KEY_UNKNOWN);
108
109 /*
110 Test that if both integer and float rec_per_key values are set,
111 the float values will be used.
112 */
113
114 // Give a value using the integer based rec_per_key
115 key.rec_per_key[1]= 1;
116 EXPECT_TRUE(key.has_records_per_key(1));
117 EXPECT_EQ(key.records_per_key(1), 1.0);
118
119 // Update the value using the API
120 key.set_records_per_key(1, 2.0);
121 EXPECT_TRUE(key.has_records_per_key(1));
122 EXPECT_EQ(key.records_per_key(1), 2.0);
123
124 // Set the value back to default/unknown
125 key.set_records_per_key(1, REC_PER_KEY_UNKNOWN);
126
127 /*
128 This result might not be intuitive but when we set the value using
129 the API, only the float value will be updated. When the float value
130 is set to default/unknown, the integer value will be used instead.
131 In pratice this is not an issue, but can be solved by setting
132 the integer value to 0, when setting the float value.
133 */
134 EXPECT_TRUE(key.has_records_per_key(1));
135 EXPECT_EQ(key.records_per_key(1), 1.0);
136
137 /*
138 Verify that we get default/unknown when also setting the integer
139 value to the default/unknown value.
140 */
141 key.rec_per_key[1]= 0;
142 EXPECT_FALSE(key.has_records_per_key(1));
143 EXPECT_EQ(key.records_per_key(1), REC_PER_KEY_UNKNOWN);
144 }
145
146 }
147