• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 19586471228

21 Nov 2025 11:36PM UTC coverage: 90.802% (+0.2%) from 90.627%
19586471228

Pull #5167

github

web-flow
Merge dc170f795 into f8eb34002
Pull Request #5167: Changes to reduce unnecessary inclusions

100849 of 111065 relevant lines covered (90.8%)

12790156.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.6
/src/tests/test_psk_db.cpp
1
/*
2
* (C) 2017 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_PSK_DB)
10

11
   #include <botan/psk_db.h>
12
   #include <botan/rng.h>
13

14
   #if defined(BOTAN_HAS_SQLITE3)
15
      #include <botan/sqlite3.h>
16
   #endif
17

18
namespace Botan_Tests {
19

20
namespace {
21

22
class Test_Map_PSK_Db : public Botan::Encrypted_PSK_Database {
1✔
23
   public:
24
      explicit Test_Map_PSK_Db(const Botan::secure_vector<uint8_t>& master_key) :
1✔
25
            Botan::Encrypted_PSK_Database(master_key) {}
1✔
26

27
      void test_entry(Test::Result& result, const std::string& index, const std::string& value) {
6✔
28
         auto i = m_vals.find(index);
6✔
29

30
         if(i == m_vals.end()) {
6✔
31
            result.test_failure("Expected to find encrypted name " + index);
×
32
         } else {
33
            result.test_eq("Encrypted value", i->second, value);
12✔
34
         }
35
      }
6✔
36

37
      void kv_set(std::string_view index, std::string_view value) override {
6✔
38
         m_vals.insert_or_assign(std::string(index), std::string(value));
18✔
39
      }
6✔
40

41
      std::string kv_get(std::string_view index) const override {
7✔
42
         auto i = m_vals.find(index);
7✔
43
         if(i == m_vals.end()) {
7✔
44
            return "";
1✔
45
         }
46
         return i->second;
6✔
47
      }
48

49
      void kv_del(std::string_view index) override {
2✔
50
         auto i = m_vals.find(index);
2✔
51
         if(i != m_vals.end()) {
2✔
52
            m_vals.erase(i);
1✔
53
         }
54
      }
2✔
55

56
      std::set<std::string> kv_get_all() const override {
2✔
57
         std::set<std::string> names;
2✔
58

59
         for(const auto& kv : m_vals) {
7✔
60
            names.insert(kv.first);
5✔
61
         }
62

63
         return names;
2✔
64
      }
×
65

66
   private:
67
      std::map<std::string, std::string, std::less<>> m_vals;
68
};
69

70
}  // namespace
71

72
class PSK_DB_Tests final : public Test {
1✔
73
   public:
74
      std::vector<Test::Result> run() override {
1✔
75
         std::vector<Test::Result> results;
1✔
76

77
         results.push_back(test_psk_db());
2✔
78

79
   #if defined(BOTAN_HAS_SQLITE3)
80
         results.push_back(test_psk_sql_db());
2✔
81
   #endif
82

83
         return results;
1✔
84
      }
×
85

86
   private:
87
      static Test::Result test_psk_db() {
1✔
88
         Test::Result result("PSK_DB");
1✔
89

90
         const Botan::secure_vector<uint8_t> zeros(32);
1✔
91
         Test_Map_PSK_Db db(zeros);
1✔
92

93
         db.set_str("name", "value");
1✔
94
         db.test_entry(result, "CUCJjJgWSa079ubutJQwlw==", "clYJSAf9CThuL96CP+rAfA==");
2✔
95
         result.test_eq("DB read", db.get_str("name"), "value");
2✔
96

97
         db.set_str("name", "value1");
1✔
98
         db.test_entry(result, "CUCJjJgWSa079ubutJQwlw==", "7R8am3x/gLawOzMp5WwIJg==");
2✔
99
         result.test_eq("DB read", db.get_str("name"), "value1");
2✔
100

101
         db.set_str("name", "value");
1✔
102
         db.test_entry(result, "CUCJjJgWSa079ubutJQwlw==", "clYJSAf9CThuL96CP+rAfA==");
2✔
103
         result.test_eq("DB read", db.get_str("name"), "value");
2✔
104

105
         db.set_str("name2", "value");
1✔
106
         db.test_entry(result, "7CvsM7HDCZsV6VsFwWylNg==", "BqVQo4rdwOmf+ItCzEmjAg==");
2✔
107
         result.test_eq("DB read", db.get_str("name2"), "value");
2✔
108

109
         db.set_vec("name2", zeros);
1✔
110
         db.test_entry(result, "7CvsM7HDCZsV6VsFwWylNg==", "x+I1bUF/fJYPOTvKwOihEPWGR1XGzVuyRdsw4n5gpBRzNR7LjH7vjw==");
2✔
111
         result.test_eq("DB read", db.get("name2"), zeros);
2✔
112

113
         // Test longer names
114
         db.set_str("leroy jeeeeeeeenkins", "chicken");
1✔
115
         db.test_entry(result, "KyYo272vlSjClM2F0OZBMlRYjr33ZXv2jN1oY8OfCEs=", "tCl1qShSTsXi9tA5Kpo9vg==");
2✔
116
         result.test_eq("DB read", db.get_str("leroy jeeeeeeeenkins"), "chicken");
2✔
117

118
         std::set<std::string> all_names = db.list_names();
1✔
119

120
         result.test_eq("Expected number of names", all_names.size(), 3);
1✔
121
         result.test_eq("Have expected name", all_names.count("name"), 1);
3✔
122
         result.test_eq("Have expected name", all_names.count("name2"), 1);
3✔
123
         result.test_eq("Have expected name", all_names.count("leroy jeeeeeeeenkins"), 1);
3✔
124

125
         db.remove("name2");
1✔
126

127
         all_names = db.list_names();
2✔
128

129
         result.test_eq("Expected number of names", all_names.size(), 2);
1✔
130
         result.test_eq("Have expected name", all_names.count("name"), 1);
3✔
131
         result.test_eq("Have expected name", all_names.count("leroy jeeeeeeeenkins"), 1);
3✔
132

133
         result.test_throws(
2✔
134
            "exception if get called on non-existent PSK", "Named PSK not located", [&]() { db.get("name2"); });
2✔
135

136
         // test that redundant remove calls accepted
137
         db.remove("name2");
1✔
138

139
         return result;
1✔
140
      }
3✔
141

142
   #if defined(BOTAN_HAS_SQLITE3)
143

144
      void test_entry(Test::Result& result,
6✔
145
                      Botan::SQL_Database& db,
146
                      const std::string& table,
147
                      const std::string& expected_name,
148
                      const std::string& expected_value) {
149
         auto stmt = db.new_statement("select psk_value from " + table + " where psk_name='" + expected_name + "'");
30✔
150

151
         bool got_it = stmt->step();
6✔
152
         result.confirm("Had expected name", got_it);
12✔
153

154
         if(got_it) {
6✔
155
            result.test_eq("Had expected value", stmt->get_str(0), expected_value);
12✔
156
         }
157
      }
6✔
158

159
      Test::Result test_psk_sql_db() {
1✔
160
         Test::Result result("PSK_DB SQL");
1✔
161

162
         const Botan::secure_vector<uint8_t> zeros(32);
1✔
163
         const Botan::secure_vector<uint8_t> not_zeros = this->rng().random_vec(32);
1✔
164

165
         const std::string table_name = "bobby";
1✔
166
         std::shared_ptr<Botan::SQL_Database> sqldb = std::make_shared<Botan::Sqlite3_Database>(":memory:");
1✔
167

168
         Botan::Encrypted_PSK_Database_SQL db(zeros, sqldb, table_name);
1✔
169
         db.set_str("name", "value");
1✔
170

171
         test_entry(result, *sqldb, table_name, "CUCJjJgWSa079ubutJQwlw==", "clYJSAf9CThuL96CP+rAfA==");
2✔
172
         result.test_eq("DB read", db.get_str("name"), "value");
2✔
173

174
         db.set_str("name", "value1");
1✔
175
         test_entry(result, *sqldb, table_name, "CUCJjJgWSa079ubutJQwlw==", "7R8am3x/gLawOzMp5WwIJg==");
2✔
176
         result.test_eq("DB read", db.get_str("name"), "value1");
2✔
177

178
         db.set_str("name", "value");
1✔
179
         test_entry(result, *sqldb, table_name, "CUCJjJgWSa079ubutJQwlw==", "clYJSAf9CThuL96CP+rAfA==");
2✔
180
         result.test_eq("DB read", db.get_str("name"), "value");
2✔
181

182
         db.set_str("name2", "value");
1✔
183
         test_entry(result, *sqldb, table_name, "7CvsM7HDCZsV6VsFwWylNg==", "BqVQo4rdwOmf+ItCzEmjAg==");
2✔
184
         result.test_eq("DB read", db.get_str("name2"), "value");
1✔
185

186
         db.set_vec("name2", zeros);
1✔
187
         test_entry(result,
2✔
188
                    *sqldb,
1✔
189
                    table_name,
190
                    "7CvsM7HDCZsV6VsFwWylNg==",
191
                    "x+I1bUF/fJYPOTvKwOihEPWGR1XGzVuyRdsw4n5gpBRzNR7LjH7vjw==");
192
         result.test_eq("DB read", db.get("name2"), zeros);
2✔
193

194
         // Test longer names
195
         db.set_str("leroy jeeeeeeeenkins", "chicken");
1✔
196
         test_entry(
2✔
197
            result, *sqldb, table_name, "KyYo272vlSjClM2F0OZBMlRYjr33ZXv2jN1oY8OfCEs=", "tCl1qShSTsXi9tA5Kpo9vg==");
1✔
198
         result.test_eq("DB read", db.get_str("leroy jeeeeeeeenkins"), "chicken");
2✔
199

200
         /*
201
         * Test that we can have another database in the same table with distinct key
202
         * without any problems.
203
         */
204
         Botan::Encrypted_PSK_Database_SQL db2(not_zeros, sqldb, table_name);
1✔
205
         db2.set_str("name", "price&value");
1✔
206
         result.test_eq("DB read", db2.get_str("name"), "price&value");
2✔
207
         result.test_eq("DB2 size", db2.list_names().size(), 1);
2✔
208

209
         std::set<std::string> all_names = db.list_names();
1✔
210

211
         result.test_eq("Expected number of names", all_names.size(), 3);
1✔
212
         result.test_eq("Have expected name", all_names.count("name"), 1);
3✔
213
         result.test_eq("Have expected name", all_names.count("name2"), 1);
3✔
214
         result.test_eq("Have expected name", all_names.count("leroy jeeeeeeeenkins"), 1);
3✔
215

216
         db.remove("name2");
1✔
217

218
         all_names = db.list_names();
2✔
219

220
         result.test_eq("Expected number of names", all_names.size(), 2);
1✔
221
         result.test_eq("Have expected name", all_names.count("name"), 1);
3✔
222
         result.test_eq("Have expected name", all_names.count("leroy jeeeeeeeenkins"), 1);
3✔
223

224
         result.test_throws(
2✔
225
            "exception if get called on non-existent PSK", "Named PSK not located", [&]() { db.get("name2"); });
2✔
226

227
         // test that redundant remove calls accepted
228
         db.remove("name2");
1✔
229

230
         return result;
1✔
231
      }
4✔
232
   #endif
233
};
234

235
BOTAN_REGISTER_TEST("misc", "psk_db", PSK_DB_Tests);
236

237
}  // namespace Botan_Tests
238

239
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc