]> git.stg.codes - stg.git/blob - tests/test_bfstream.cpp
Ticket 37. WriteTime() changed to WriteString() and formatTime() added
[stg.git] / tests / test_bfstream.cpp
1 #include "tut/tut.hpp"
2
3 #include "longstring.h"
4
5 #include "stg/bfstream.h"
6 #include "stg/os_int.h"
7
8 #include <algorithm>
9 #include <string>
10 #include <cstring>
11
12 namespace
13 {
14
15 class TRACKER
16 {
17     public:
18         TRACKER() : m_lastSize(0), m_callCount(0), m_lastBlock(NULL) {}
19         ~TRACKER() { delete[] m_lastBlock; }
20         bool Call(const void * block, size_t size)
21         {
22         delete[] m_lastBlock;
23         if (size > 0)
24             {
25             m_lastBlock = new char[size];
26             memcpy(m_lastBlock,  block, size);
27             m_result.append(m_lastBlock, size);
28             }
29         else
30             m_lastBlock = NULL;
31         m_lastSize = size;
32         ++m_callCount;
33         return true;
34         }
35         size_t LastSize() const { return m_lastSize; }
36         size_t CallCount() const { return m_callCount; }
37         const void * LastBlock() const { return m_lastBlock; }
38
39         const std::string& Result() const { return m_result; }
40
41     private:
42         size_t m_lastSize;
43         size_t m_callCount;
44         char * m_lastBlock;
45
46         std::string m_result;
47 };
48
49 bool DecryptCallback(const void * block, size_t size, void * data);
50
51 class Decryptor
52 {
53     public:
54         Decryptor(const std::string & key)
55             : m_stream(key, DecryptCallback, this)
56         {}
57
58         bool Call(const void * block, size_t size)
59         {
60             m_stream.Put(block, size);
61             return true;
62         }
63
64         bool Put(const void * block, size_t size)
65         {
66             const char * data = static_cast<const char *>(block);
67             size = strnlen(data, size);
68             m_result.append(data, size);
69             return true;
70         }
71
72         void Flush()
73         {
74             m_stream.Put(NULL, 0);
75         }
76
77         const std::string & Result() const { return m_result; }
78
79     private:
80         STG::DECRYPT_STREAM m_stream;
81         std::string m_result;
82 };
83
84 bool EncryptCallback(const void * block, size_t size, void * data)
85 {
86 Decryptor & decryptor = *static_cast<Decryptor *>(data);
87 return decryptor.Call(block, size);
88 }
89
90 bool DecryptCallback(const void * block, size_t size, void * data)
91 {
92 Decryptor & decryptor = *static_cast<Decryptor *>(data);
93 return decryptor.Put(block, size);
94 }
95
96 bool Callback(const void * block, size_t size, void * data)
97 {
98 TRACKER & tracker = *static_cast<TRACKER *>(data);
99 return tracker.Call(block, size);
100 }
101
102 }
103
104 namespace tut
105 {
106     struct bfstream_data {
107     };
108
109     typedef test_group<bfstream_data> tg;
110     tg bfstream_test_group("BFStream tests group");
111
112     typedef tg::object testobject;
113
114     template<>
115     template<>
116     void testobject::test<1>()
117     {
118         set_test_name("Check bfstream mechanics");
119
120         TRACKER tracker;
121         STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
122         ensure_equals("CallCount() == 0 after construction", tracker.CallCount(), 0);
123
124         uint32_t block[2] = {0x12345678, 0x87654321};
125         stream.Put(&block[0], sizeof(block[0]));
126         ensure_equals("CallCount() == 0 after first put", tracker.CallCount(), 0);
127         stream.Put(&block[1], sizeof(block[1]));
128         ensure_equals("CallCount() == 1 after second put", tracker.CallCount(), 1);
129
130         uint32_t block2[4] = {0x12345678, 0x87654321, 0x12345678, 0x87654321};
131         stream.Put(&block2[0], sizeof(block2[0]) * 3);
132         ensure_equals("CallCount() == 2 after third put", tracker.CallCount(), 2);
133         stream.Put(&block2[3], sizeof(block2[3]));
134         ensure_equals("CallCount() == 3 after fourth put", tracker.CallCount(), 3);
135     }
136
137     template<>
138     template<>
139     void testobject::test<2>()
140     {
141         set_test_name("Check bfstream encryption");
142
143         TRACKER tracker;
144         STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
145
146         uint32_t block[2] = {0x12345678, 0x87654321};
147         stream.Put(&block[0], sizeof(block[0]));
148         ensure_equals("LastSize() == 0 after first put", tracker.LastSize(), 0);
149         ensure_equals("LastBlock() == NULL after first put", tracker.LastBlock(), static_cast<const void *>(NULL));
150         stream.Put(&block[1], sizeof(block[1]));
151         ensure_equals("LastSize() == 8 after second put", tracker.LastSize(), 8);
152         const uint32_t * ptr = static_cast<const uint32_t *>(tracker.LastBlock());
153         ensure_equals("ptr[0] == 0xd3988cd after second put", ptr[0], 0xd3988cd);
154         ensure_equals("ptr[1] == 0x7996c6d6 after second put", ptr[1], 0x7996c6d6);
155
156         uint32_t block2[4] = {0x12345678, 0x87654321, 0x12345678, 0x87654321};
157         stream.Put(&block2[0], sizeof(block2[0]) * 3);
158         ensure_equals("LastSize() == 8 after third put", tracker.LastSize(), 8);
159         ptr = static_cast<const uint32_t *>(tracker.LastBlock());
160         ensure_equals("ptr[0] == 0xd3988cd after third put", ptr[0], 0xd3988cd);
161         ensure_equals("ptr[1] == 0x7996c6d6 after third put", ptr[1], 0x7996c6d6);
162
163         stream.Put(&block2[3], sizeof(block2[3]));
164         ensure_equals("LastSize() == 8 after fourth put", tracker.LastSize(), 8);
165         ptr = static_cast<const uint32_t *>(tracker.LastBlock());
166         ensure_equals("ptr[0] == 0xd3988cd after fourth put", ptr[0], 0xd3988cd);
167         ensure_equals("ptr[1] == 0x7996c6d6 after fourth put", ptr[1], 0x7996c6d6);
168     }
169
170     template<>
171     template<>
172     void testobject::test<3>()
173     {
174         set_test_name("Check bfstream long string processing");
175
176         TRACKER tracker;
177         STG::ENCRYPT_STREAM estream("pr7Hhen", Callback, &tracker);
178         std::string source = "This is a test long string for checking stream encryption/decryption. \"abcdefghijklmnopqrstuvwxyz 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ\"";
179         char buffer[source.length() + 9];
180         memset(buffer, 0, sizeof(buffer));
181
182         estream.Put(source.c_str(), source.length() + 1, true);
183         ensure("Encryption long string LastSize()", tracker.LastSize() >= source.length() + 1);
184         ensure("Encryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
185         memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
186
187         STG::DECRYPT_STREAM dstream("pr7Hhen", Callback, &tracker);
188         dstream.Put(buffer, sizeof(buffer), true);
189         ensure("Decryption long string LastSize() decryption", tracker.LastSize() >= sizeof(buffer));
190         ensure("Decryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
191         memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
192
193         ensure_equals("Decrypt(Encrypt(source)) == source", std::string(buffer), source);
194     }
195
196     template<>
197     template<>
198     void testobject::test<4>()
199     {
200         set_test_name("Check bfstream very long string processing");
201
202         Decryptor decryptor("pr7Hhen");
203         STG::ENCRYPT_STREAM estream("pr7Hhen", EncryptCallback, &decryptor);
204         //char buffer[source.length() + 9];
205         //memset(buffer, 0, sizeof(buffer));
206
207         estream.Put(longString.c_str(), longString.length() + 1, true);
208         //ensure("Encryption long string LastSize()", tracker.LastSize() >= source.length() + 1);
209         //ensure("Encryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
210         //memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
211
212         //dstream.Put(buffer, sizeof(buffer), true);
213         //ensure("Decryption long string LastSize() decryption", tracker.LastSize() >= sizeof(buffer));
214         //ensure("Decryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
215         //memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
216
217         ensure_equals("Decrypt(Encrypt(source)) == source", decryptor.Result(), longString);
218     }
219
220     template<>
221     template<>
222     void testobject::test<5>()
223     {
224         set_test_name("Check bfstream mechanics");
225
226         TRACKER tracker;
227         STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
228         ensure_equals("CallCount() == 0 after construction", tracker.CallCount(), 0);
229
230         uint32_t block[2] = {0x12345678, 0x87654321};
231         stream.Put(&block[0], sizeof(block[0]));
232         ensure_equals("CallCount() == 0 after first put", tracker.CallCount(), 0);
233         stream.Put(&block[1], sizeof(block[1]));
234         ensure_equals("CallCount() == 1 after second put", tracker.CallCount(), 1);
235         stream.Put(&block[0], 0, true); // Check last callback
236         ensure_equals("CallCount() == 2 after third (null) put", tracker.CallCount(), 2);
237     }
238
239 }