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

randombit / botan / 22020273955

14 Feb 2026 04:02PM UTC coverage: 90.059% (-0.005%) from 90.064%
22020273955

push

github

web-flow
Merge pull request #5328 from randombit/jack/test-predicates

Change Test::Result integer and bool predicates to be specifically named

102238 of 113523 relevant lines covered (90.06%)

11567860.88 hits per line

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

86.36
/src/tests/test_compression.cpp
1
/*
2
* (C) 2015 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_COMPRESSION)
10
   #include <botan/compression.h>
11
   #include <botan/rng.h>
12
   #include <cstring>
13
#endif
14

15
namespace Botan_Tests {
16

17
#if defined(BOTAN_HAS_COMPRESSION)
18

19
namespace {
20

21
const char* const COMPRESSION_TEST_TEXT =
22
   "'Twas brillig, and the slithy toves"
23
   "Did gyre and gimble in the wabe:"
24
   "All mimsy were the borogoves,"
25
   "And the mome raths outgrabe."
26

27
   "'Beware the Jabberwock, my son!"
28
   "The jaws that bite, the claws that catch!"
29
   "Beware the Jubjub bird, and shun"
30
   "The frumious Bandersnatch!'"
31

32
   "He took his vorpal sword in hand;"
33
   "Long time the manxome foe he sought-"
34
   "So rested he by the Tumtum tree"
35
   "And stood awhile in thought."
36

37
   "And, as in uffish thought he stood,"
38
   "The Jabberwock, with eyes of flame,"
39
   "Came whiffling through the tulgey wood,"
40
   "And burbled as it came!"
41

42
   "One, two! One, two! And through and through"
43
   "The vorpal blade went snicker-snack!"
44
   "He left it dead, and with its head"
45
   "He went galumphing back."
46

47
   "'And hast thou slain the Jabberwock?"
48
   "Come to my arms, my beamish boy!"
49
   "O frabjous day! Callooh! Callay!'"
50
   "He chortled in his joy."
51

52
   "'Twas brillig, and the slithy toves"
53
   "Did gyre and gimble in the wabe:"
54
   "All mimsy were the borogoves,"
55
   "And the mome raths outgrabe.";
56

57
class Compression_Tests final : public Test {
1✔
58
   public:
59
      std::vector<Test::Result> run() override {
1✔
60
         std::vector<Test::Result> results;
1✔
61
         const size_t text_len = std::strlen(COMPRESSION_TEST_TEXT);
1✔
62

63
         for(const std::string algo : {"zlib", "deflate", "gzip", "bz2", "lzma"}) {
6✔
64
            try {
5✔
65
               Test::Result result(algo + " compression");
5✔
66

67
               result.start_timer();
5✔
68

69
               auto c = Botan::Compression_Algorithm::create(algo);
5✔
70
               auto d = Botan::Decompression_Algorithm::create(algo);
5✔
71

72
               if(!c || !d) {
5✔
73
                  result.note_missing(algo);
×
74
                  continue;
×
75
               }
76

77
               result.test_ne("Not the same name", c->name(), d->name());
5✔
78

79
               const Botan::secure_vector<uint8_t> empty;
5✔
80
               const Botan::secure_vector<uint8_t> all_zeros(text_len, 0);
5✔
81
               const Botan::secure_vector<uint8_t> random_binary = this->rng().random_vec(text_len);
5✔
82
               const Botan::secure_vector<uint8_t> short_text = {'f', 'o', 'o', '\n'};
5✔
83

84
               const uint8_t* textb = reinterpret_cast<const uint8_t*>(COMPRESSION_TEST_TEXT);
5✔
85
               const Botan::secure_vector<uint8_t> text(textb, textb + text_len);
5✔
86

87
               const size_t c1_e = run_compression(result, 1, *c, *d, empty);
5✔
88
               const size_t c9_e = run_compression(result, 9, *c, *d, empty);
5✔
89
               const size_t c1_z = run_compression(result, 1, *c, *d, all_zeros);
5✔
90
               const size_t c9_z = run_compression(result, 9, *c, *d, all_zeros);
5✔
91
               const size_t c1_r = run_compression(result, 1, *c, *d, random_binary);
5✔
92
               const size_t c9_r = run_compression(result, 9, *c, *d, random_binary);
5✔
93
               const size_t c1_t = run_compression(result, 1, *c, *d, text);
5✔
94
               const size_t c9_t = run_compression(result, 9, *c, *d, text);
5✔
95
               const size_t c1_s = run_compression(result, 1, *c, *d, short_text);
5✔
96
               const size_t c9_s = run_compression(result, 9, *c, *d, short_text);
5✔
97

98
               result.test_sz_gte("Empty input L1 compresses to non-empty output", c1_e, 1);
5✔
99
               result.test_sz_gte("Empty input L9 compresses to non-empty output", c9_e, 1);
5✔
100

101
               // We assume that Level 9 is better than Level 1, but this is not
102
               // guaranteed (see GitHub #3896). Hence, we assert that level 9
103
               // it is at most 10% worse than level 1.
104
               result.test_sz_gte("Level 9 compresses empty at least as well as level 1", c1_e + (c1_e / 10), c9_e);
5✔
105
               result.test_sz_gte("Level 9 compresses zeros at least as well as level 1", c1_z + (c1_z / 10), c9_z);
5✔
106
               result.test_sz_gte("Level 9 compresses random at least as well as level 1", c1_r + (c1_r / 10), c9_r);
5✔
107
               result.test_sz_gte("Level 9 compresses text at least as well as level 1", c1_t + (c1_t / 10), c9_t);
5✔
108
               result.test_sz_gte(
10✔
109
                  "Level 9 compresses short text at least as well as level 1", c1_s + (c1_s / 10), c9_s);
5✔
110

111
               result.test_sz_lt("Zeros compresses much better than text", c1_z / 8, c1_t);
5✔
112
               result.test_sz_lt("Text compresses much better than random", c1_t / 2, c1_r);
5✔
113

114
               result.end_timer();
5✔
115

116
               results.emplace_back(result);
5✔
117
            } catch(std::exception& e) {
30✔
118
               results.emplace_back(Test::Result::Failure("testing " + algo, e.what()));
×
119
            }
×
120
         }
5✔
121

122
         return results;
1✔
123
      }
5✔
124

125
   private:
126
      // Returns # of bytes of compressed message
127
      size_t run_compression(Test::Result& result,
50✔
128
                             size_t level,
129
                             Botan::Compression_Algorithm& c,
130
                             Botan::Decompression_Algorithm& d,
131
                             const Botan::secure_vector<uint8_t>& msg) {
132
         Botan::secure_vector<uint8_t> compressed(2 * msg.size());
50✔
133

134
         for(const bool with_flush : {true, false}) {
150✔
135
            try {
100✔
136
               compressed = msg;
100✔
137

138
               c.start(level);
100✔
139
               c.update(compressed, 0, false);
100✔
140

141
               if(with_flush) {
100✔
142
                  Botan::secure_vector<uint8_t> flush_bits;
50✔
143
                  c.update(flush_bits, 0, true);
50✔
144
                  compressed += flush_bits;
50✔
145
               }
50✔
146

147
               Botan::secure_vector<uint8_t> final_bits;
100✔
148
               c.finish(final_bits);
100✔
149
               compressed += final_bits;
100✔
150

151
               Botan::secure_vector<uint8_t> decompressed = compressed;
100✔
152
               d.start();
100✔
153
               d.update(decompressed);
100✔
154

155
               Botan::secure_vector<uint8_t> final_outputs;
100✔
156
               d.finish(final_outputs);
100✔
157

158
               decompressed += final_outputs;
100✔
159

160
               result.test_eq("compression round tripped", msg, decompressed);
100✔
161
            } catch(Botan::Exception& e) {
300✔
162
               result.test_failure(e.what());
×
163
            }
×
164
         }
165

166
         return compressed.size();
50✔
167
      }
50✔
168
};
169

170
BOTAN_REGISTER_TEST("compression", "compression_tests", Compression_Tests);
171

172
class CompressionCreate_Tests final : public Test {
1✔
173
   public:
174
      std::vector<Test::Result> run() override {
1✔
175
         std::vector<Test::Result> results;
1✔
176

177
         for(const std::string algo : {"zlib", "deflate", "gzip", "bz2", "lzma"}) {
6✔
178
            try {
5✔
179
               Test::Result result(algo + " create compression");
5✔
180

181
               auto c1 = Botan::Compression_Algorithm::create(algo);
5✔
182
               auto d1 = Botan::Decompression_Algorithm::create(algo);
5✔
183

184
               if(!c1 || !d1) {
5✔
185
                  result.note_missing(algo);
×
186
                  continue;
×
187
               }
188
               result.test_ne("Not the same name after create", c1->name(), d1->name());
5✔
189

190
               auto c2 = Botan::Compression_Algorithm::create_or_throw(algo);
5✔
191
               auto d2 = Botan::Decompression_Algorithm::create_or_throw(algo);
5✔
192

193
               if(!c2 || !d2) {
5✔
194
                  result.note_missing(algo);
×
195
                  continue;
×
196
               }
197
               result.test_ne("Not the same name after create_or_throw", c2->name(), d2->name());
5✔
198

199
               results.emplace_back(result);
5✔
200
            } catch(std::exception& e) {
20✔
201
               results.emplace_back(Test::Result::Failure("testing " + algo, e.what()));
×
202
            }
×
203
         }
5✔
204

205
         {
1✔
206
            Test::Result result("create invalid compression");
1✔
207
            result.test_throws("lookup error", "Unavailable Compression bogocompress", [&]() {
1✔
208
               Botan::Compression_Algorithm::create_or_throw("bogocompress");
1✔
209
            });
×
210
            result.test_throws("lookup error", "Unavailable Decompression bogocompress", [&]() {
1✔
211
               Botan::Decompression_Algorithm::create_or_throw("bogocompress");
1✔
212
            });
×
213
            results.emplace_back(result);
1✔
214
         }
1✔
215

216
         return results;
1✔
217
      }
×
218
};
219

220
BOTAN_REGISTER_TEST("compression", "create_compression", CompressionCreate_Tests);
221

222
}  // namespace
223

224
#endif
225

226
}  // namespace Botan_Tests
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