ruby-libstorj 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/Gemfile +23 -0
  6. data/Gemfile.lock +111 -0
  7. data/Guardfile +21 -0
  8. data/LICENSE +502 -0
  9. data/README.md +262 -0
  10. data/Rakefile +76 -0
  11. data/ext/libstorj/.gitignore +47 -0
  12. data/ext/libstorj/.travis.yml +27 -0
  13. data/ext/libstorj/Doxyfile +2427 -0
  14. data/ext/libstorj/LICENSE +502 -0
  15. data/ext/libstorj/Makefile.am +6 -0
  16. data/ext/libstorj/README.md +198 -0
  17. data/ext/libstorj/autogen.sh +3 -0
  18. data/ext/libstorj/configure.ac +64 -0
  19. data/ext/libstorj/depends/Makefile +153 -0
  20. data/ext/libstorj/depends/config.guess +1462 -0
  21. data/ext/libstorj/depends/config.sub +1823 -0
  22. data/ext/libstorj/depends/extract-osx-sdk.sh +33 -0
  23. data/ext/libstorj/depends/packages/cctools.mk +7 -0
  24. data/ext/libstorj/depends/packages/clang.mk +7 -0
  25. data/ext/libstorj/depends/packages/gmp.mk +23 -0
  26. data/ext/libstorj/depends/packages/gnutls.mk +25 -0
  27. data/ext/libstorj/depends/packages/json-c.mk +7 -0
  28. data/ext/libstorj/depends/packages/libcurl.mk +39 -0
  29. data/ext/libstorj/depends/packages/libmicrohttpd.mk +7 -0
  30. data/ext/libstorj/depends/packages/libuv.mk +7 -0
  31. data/ext/libstorj/depends/packages/nettle.mk +30 -0
  32. data/ext/libstorj/libstorj.pc.in +11 -0
  33. data/ext/libstorj/src/Makefile.am +23 -0
  34. data/ext/libstorj/src/bip39.c +233 -0
  35. data/ext/libstorj/src/bip39.h +64 -0
  36. data/ext/libstorj/src/bip39_english.h +2074 -0
  37. data/ext/libstorj/src/cli.c +1494 -0
  38. data/ext/libstorj/src/crypto.c +525 -0
  39. data/ext/libstorj/src/crypto.h +178 -0
  40. data/ext/libstorj/src/downloader.c +1923 -0
  41. data/ext/libstorj/src/downloader.h +163 -0
  42. data/ext/libstorj/src/http.c +688 -0
  43. data/ext/libstorj/src/http.h +175 -0
  44. data/ext/libstorj/src/rs.c +962 -0
  45. data/ext/libstorj/src/rs.h +99 -0
  46. data/ext/libstorj/src/storj.c +1523 -0
  47. data/ext/libstorj/src/storj.h +1014 -0
  48. data/ext/libstorj/src/uploader.c +2736 -0
  49. data/ext/libstorj/src/uploader.h +181 -0
  50. data/ext/libstorj/src/utils.c +336 -0
  51. data/ext/libstorj/src/utils.h +65 -0
  52. data/ext/libstorj/test/Makefile.am +27 -0
  53. data/ext/libstorj/test/mockbridge.c +260 -0
  54. data/ext/libstorj/test/mockbridge.json +687 -0
  55. data/ext/libstorj/test/mockbridgeinfo.json +1836 -0
  56. data/ext/libstorj/test/mockfarmer.c +358 -0
  57. data/ext/libstorj/test/storjtests.h +41 -0
  58. data/ext/libstorj/test/tests.c +1617 -0
  59. data/ext/libstorj/test/tests_rs.c +869 -0
  60. data/ext/ruby-libstorj/extconf.rb +8 -0
  61. data/ext/ruby-libstorj/ruby-libstorj.cc +17 -0
  62. data/lib/ruby-libstorj.rb +1 -0
  63. data/lib/ruby-libstorj/arg_forwarding_task.rb +58 -0
  64. data/lib/ruby-libstorj/env.rb +178 -0
  65. data/lib/ruby-libstorj/ext/bucket.rb +71 -0
  66. data/lib/ruby-libstorj/ext/create_bucket_request.rb +53 -0
  67. data/lib/ruby-libstorj/ext/curl_code.rb +139 -0
  68. data/lib/ruby-libstorj/ext/ext.rb +71 -0
  69. data/lib/ruby-libstorj/ext/file.rb +84 -0
  70. data/lib/ruby-libstorj/ext/get_bucket_request.rb +45 -0
  71. data/lib/ruby-libstorj/ext/json_request.rb +51 -0
  72. data/lib/ruby-libstorj/ext/list_files_request.rb +63 -0
  73. data/lib/ruby-libstorj/ext/types.rb +226 -0
  74. data/lib/ruby-libstorj/ext/upload_options.rb +38 -0
  75. data/lib/ruby-libstorj/libstorj.rb +22 -0
  76. data/lib/ruby-libstorj/mixins/storj.rb +27 -0
  77. data/lib/ruby-libstorj/struct.rb +42 -0
  78. data/ruby-libstorj.gemspec +57 -0
  79. data/spec/helpers/options.yml.example +22 -0
  80. data/spec/helpers/shared_rake_examples.rb +132 -0
  81. data/spec/helpers/storj_options.rb +96 -0
  82. data/spec/helpers/upload.data +3 -0
  83. data/spec/helpers/upload.data.sha256 +1 -0
  84. data/spec/libstorj_spec.rb +0 -0
  85. data/spec/ruby-libstorj/arg_forwarding_task_spec.rb +311 -0
  86. data/spec/ruby-libstorj/env_spec.rb +353 -0
  87. data/spec/ruby-libstorj/ext_spec.rb +75 -0
  88. data/spec/ruby-libstorj/json_request_spec.rb +13 -0
  89. data/spec/ruby-libstorj/libstorj_spec.rb +81 -0
  90. data/spec/ruby-libstorj/struct_spec.rb +64 -0
  91. data/spec/spec_helper.rb +113 -0
  92. metadata +136 -0
@@ -0,0 +1,358 @@
1
+ #include <nettle/aes.h>
2
+ #include <nettle/ctr.h>
3
+ #include <nettle/ctr.h>
4
+
5
+ #include "storjtests.h"
6
+ #include "../src/rs.h"
7
+
8
+ static int e_count = 0;
9
+ static int i_count = 0;
10
+ static char* data = NULL;
11
+
12
+ static void setup_test_farmer_data(int shard_bytes, int shard_bytes_sent)
13
+ {
14
+ // check if data already setu
15
+ if (data) {
16
+ return;
17
+ }
18
+
19
+ struct aes256_ctx *ctx = malloc(sizeof(struct aes256_ctx));
20
+
21
+ // mnemonic: abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
22
+ // bucket_id: 368be0816766b28fd5f43af5
23
+ // file_id: 998960317b6725a3f8080c2b
24
+ uint8_t encrypt_key[32] = {215,99,0,133,172,219,64,35,54,53,171,23,146,160,
25
+ 81,126,137,21,253,171,48,217,184,188,8,137,3,
26
+ 4,83,50,30,251};
27
+ uint8_t ctr[16] = {70,219,247,135,162,7,93,193,44,123,188,234,203,115,129,82};
28
+ aes256_set_encrypt_key(ctx, encrypt_key);
29
+
30
+ int total_data_shards = 14;
31
+ int total_parity_shards = 4;
32
+ int total_shards = total_data_shards + total_parity_shards;
33
+ int total_size = shard_bytes * total_shards;
34
+
35
+ data = calloc(total_size, sizeof(char));
36
+ char *bytes = "abcdefghijklmn";
37
+ for (int i = 0; i < strlen(bytes); i++) {
38
+ memset(data + (i * shard_bytes), bytes[i], shard_bytes);
39
+ }
40
+
41
+ ctr_crypt(ctx, (nettle_cipher_func *)aes256_encrypt,
42
+ AES_BLOCK_SIZE, ctr,
43
+ total_size, (uint8_t *)data, (uint8_t *)data);
44
+
45
+ reed_solomon* rs = NULL;
46
+ uint8_t **data_blocks = NULL;
47
+ uint8_t **fec_blocks = NULL;
48
+ fec_init();
49
+
50
+ data_blocks = (uint8_t**)malloc(total_data_shards * sizeof(uint8_t *));
51
+ if (!data_blocks) {
52
+ fprintf(stderr, "memory error: unable to malloc");
53
+ exit(1);
54
+ }
55
+
56
+ for (int i = 0; i < total_data_shards; i++) {
57
+ data_blocks[i] = data + i * shard_bytes;
58
+ }
59
+
60
+ fec_blocks = (uint8_t**)malloc(total_parity_shards * sizeof(uint8_t *));
61
+ if (!fec_blocks) {
62
+ fprintf(stderr, "memory error: unable to malloc");
63
+ exit(1);
64
+ }
65
+
66
+ for (int i = 0; i < total_parity_shards; i++) {
67
+ fec_blocks[i] = data + (total_data_shards + i) * shard_bytes;
68
+ }
69
+
70
+ rs = reed_solomon_new(total_data_shards, total_parity_shards);
71
+ reed_solomon_encode2(rs, data_blocks, fec_blocks, total_shards, shard_bytes, total_size);
72
+ reed_solomon_release(rs);
73
+
74
+ free(data_blocks);
75
+ free(fec_blocks);
76
+ free(ctx);
77
+ }
78
+
79
+ static void farmer_request_completed(void *cls,
80
+ struct MHD_Connection *connection,
81
+ void **con_cls,
82
+ enum MHD_RequestTerminationCode toe)
83
+ {
84
+ *con_cls = NULL;
85
+ }
86
+
87
+ int mock_farmer_shard_server(void *cls,
88
+ struct MHD_Connection *connection,
89
+ const char *url,
90
+ const char *method,
91
+ const char *version,
92
+ const char *upload_data,
93
+ size_t *upload_data_size,
94
+ void **con_cls)
95
+ {
96
+ const char *encoding = MHD_lookup_connection_value(connection,
97
+ MHD_HEADER_KIND,
98
+ MHD_HTTP_HEADER_CONTENT_TYPE);
99
+
100
+ if (NULL == *con_cls) {
101
+
102
+ *con_cls = (void *)connection;
103
+
104
+ return MHD_YES;
105
+ }
106
+
107
+ if (0 == strcmp(method, "POST")) {
108
+
109
+ if (*upload_data_size != 0) {
110
+ // TODO check upload_data
111
+ *upload_data_size = 0;
112
+ return MHD_YES;
113
+ }
114
+
115
+ int ret;
116
+ struct MHD_Response *response;
117
+ int status_code = MHD_HTTP_NOT_FOUND;
118
+
119
+ if (0 == strcmp(url, "/")) {
120
+ status_code = MHD_HTTP_OK;
121
+ } else if (0 == strcmp(url, "/shards/179723620bfce52a6efaa6d311811cd9a31c51dc")) {
122
+ status_code = MHD_HTTP_OK;
123
+ } else if (0 == strcmp(url, "/shards/3920fcb1acf8d773bdff94edd293b57e1506073d")) {
124
+ status_code = MHD_HTTP_OK;
125
+ } else if (0 == strcmp(url, "/shards/76ec05cdfa1bc0810c5a555350d1e4cb81b01524")) {
126
+ status_code = MHD_HTTP_OK;
127
+ } else if (0 == strcmp(url, "/shards/4a9986ed3ec84a8a1b62b8ce9770002cf9aff02a")) {
128
+ status_code = MHD_HTTP_OK;
129
+ } else if (0 == strcmp(url, "/shards/76d9efb59a35a3c3862bbfb489ab1ed916f3f0d3")) {
130
+ status_code = MHD_HTTP_OK;
131
+ } else if (0 == strcmp(url, "/shards/a590ff71ca93662d63942fc2dcc2125cd592a4d4")) {
132
+ status_code = MHD_HTTP_OK;
133
+ } else if (0 == strcmp(url, "/shards/1391bf1eb215941e84bd8c52201511041580918e")) {
134
+ if (i_count == 0) {
135
+ i_count += 1;
136
+ } else {
137
+ status_code = MHD_HTTP_OK;
138
+ }
139
+ } else if (0 == strcmp(url, "/shards/b6a676b696751baa9c04d82096a35107ca7f46b6")) {
140
+ status_code = MHD_HTTP_OK;
141
+ } else if (0 == strcmp(url, "/shards/b88b80d9f0942b90a86274b53e5ab3c8fae614de")) {
142
+ status_code = MHD_HTTP_OK;
143
+ } else if (0 == strcmp(url, "/shards/7afaf8bf5bbc6e0f69a4369db38d66c34caa47b5")) {
144
+ status_code = MHD_HTTP_OK;
145
+ } else if (0 == strcmp(url, "/shards/a51df80009ca689b9b05c84ec6511a1bfcbd53af")) {
146
+ status_code = MHD_HTTP_OK;
147
+ } else if (0 == strcmp(url, "/shards/a8f3fb43cc3a2ebbace4e435a49c4ddbc4c2e624")) {
148
+ status_code = MHD_HTTP_OK;
149
+ } else if (0 == strcmp(url, "/shards/04e21b32ffefb39c93023006148a6fcdd4fed66a")) {
150
+ status_code = MHD_HTTP_OK;
151
+ } else if (0 == strcmp(url, "/shards/0eb2a9961b3fd7752925af681784fbcb3483e211")) {
152
+ status_code = MHD_HTTP_OK;
153
+ } else if (0 == strcmp(url, "/shards/e3fabe31ef120978b8d95a1d6cc705f25086da52")) {
154
+ status_code = MHD_HTTP_OK;
155
+ } else if (0 == strcmp(url, "/shards/817de8fcdd64fb2adcb5f86bbdc2993879bf7c14")) {
156
+ status_code = MHD_HTTP_OK;
157
+ } else if (0 == strcmp(url, "/shards/9d5e980402a69e711b6176c268bbc059d7b5fb1f")) {
158
+ status_code = MHD_HTTP_OK;
159
+ } else if (0 == strcmp(url, "/shards/ec4a0f16ab581872ead75f6c6a681eb3c7861355")) {
160
+ status_code = MHD_HTTP_OK;
161
+ } else if (0 == strcmp(url, "/shards/7114c67d5d18884c51e5f2efd97803f95f7ddc18")) {
162
+ status_code = MHD_HTTP_OK;
163
+ } else if (0 == strcmp(url, "/shards/9354285b6750e5dff3fb6024f12826e8ab60007c")) {
164
+ status_code = MHD_HTTP_OK;
165
+ } else if (0 == strcmp(url, "/shards/eb342afde185b4f14477e9df81f85830cdd2cf12")) {
166
+ status_code = MHD_HTTP_OK;
167
+ } else if (0 == strcmp(url, "/shards/5dc5687381a7a09cdc98fe97cfcb1402ce8a1157")) {
168
+ status_code = MHD_HTTP_OK;
169
+ } else if (0 == strcmp(url, "/shards/a16fdcfe8b8acd2d2ba8a6889aaf74f1b13004bb")) {
170
+ status_code = MHD_HTTP_OK;
171
+ } else if (0 == strcmp(url, "/shards/db4af3d07dc90b0125cf465de4be1a10a478f9e4")) {
172
+ status_code = MHD_HTTP_OK;
173
+ } else if (0 == strcmp(url, "/shards/bf1e4713257129d525f1381d4104c217c13cb42f")) {
174
+ status_code = MHD_HTTP_OK;
175
+
176
+ // PARITY SHARDS
177
+ } else if (0 == strcmp(url, "/shards/a058c13bf955d1d6134ab37ad6210de9cf539668")) {
178
+ status_code = MHD_HTTP_OK;
179
+ } else if (0 == strcmp(url, "/shards/f08c086703e511d38b0529afe6cc64f35b40bf1f")) {
180
+ status_code = MHD_HTTP_OK;
181
+ } else if (0 == strcmp(url, "/shards/a549cec8729de18e021c72b6a17009e0381b7bc6")) {
182
+ status_code = MHD_HTTP_OK;
183
+ } else if (0 == strcmp(url, "/shards/e0a3e7539912f15c83893f368cfe55e7a0909fbb")) {
184
+ status_code = MHD_HTTP_OK;
185
+ } else if (0 == strcmp(url, "/shards/0ec6fe684d01530ed2311c9c13a77d63b1d668c5")) {
186
+ status_code = MHD_HTTP_OK;
187
+ } else if (0 == strcmp(url, "/shards/c012be824494db131425a765d9d0bb390cd7c3d0")) {
188
+ status_code = MHD_HTTP_OK;
189
+ } else if (0 == strcmp(url, "/shards/76d463057e1631644b7b4c89170496b6a5879965")) {
190
+ status_code = MHD_HTTP_OK;
191
+ } else if (0 == strcmp(url, "/shards/e2b4704e8a308c115e989781f33f8c29b931961b")) {
192
+ status_code = MHD_HTTP_OK;
193
+ } else if (0 == strcmp(url, "/shards/251dc66f81cc78c70afbd139042df66eb0d9336e")) {
194
+ status_code = MHD_HTTP_OK;
195
+ } else if (0 == strcmp(url, "/shards/d1e0c5f9f08ab1f293a4559273a8a119f791647a")) {
196
+ status_code = MHD_HTTP_OK;
197
+ } else {
198
+ printf("url: %s\n", url);
199
+ }
200
+
201
+ char *page = "";
202
+ response = MHD_create_response_from_buffer(strlen(page),
203
+ (void *) page,
204
+ MHD_RESPMEM_PERSISTENT);
205
+ if (!response) {
206
+ return MHD_NO;
207
+ }
208
+
209
+ ret = MHD_queue_response(connection, status_code, response);
210
+ MHD_destroy_response(response);
211
+
212
+ return ret;
213
+ }
214
+
215
+ if (0 == strcmp(method, "GET")) {
216
+
217
+ int shard_bytes = 16777216;
218
+ int shard_bytes_sent = 16777216;
219
+ setup_test_farmer_data(shard_bytes, shard_bytes_sent);
220
+
221
+ struct MHD_Response *response;
222
+
223
+ int status_code = MHD_HTTP_NOT_FOUND;
224
+ char *page = NULL;
225
+
226
+ int ret;
227
+
228
+ if (0 == strcmp(url, "/shards/269e72f24703be80bbb10499c91dc9b2022c4dc3")) {
229
+ page = calloc(shard_bytes + 1, sizeof(char));
230
+ memcpy(page, data + shard_bytes * 0, shard_bytes);
231
+ status_code = MHD_HTTP_OK;
232
+ } else if (0 == strcmp(url, "/shards/17416a592487d7b1b74c100448c8296122d8aff8")) {
233
+ page = calloc(shard_bytes + 1, sizeof(char));
234
+ memcpy(page, data + shard_bytes * 1, shard_bytes);
235
+ status_code = MHD_HTTP_OK;
236
+ } else if (0 == strcmp(url, "/shards/83cf5eaf2311a1ae9699772d9bafbb3e369a41cc")) {
237
+ page = calloc(shard_bytes + 1, sizeof(char));
238
+ memcpy(page, data + shard_bytes * 2, shard_bytes);
239
+ status_code = MHD_HTTP_OK;
240
+ } else if (0 == strcmp(url, "/shards/214ed86cb1287fe0fd18c174eecbf84341bf2655")) {
241
+ page = calloc(shard_bytes + 1, sizeof(char));
242
+ memcpy(page, data + shard_bytes * 3, shard_bytes);
243
+ status_code = MHD_HTTP_OK;
244
+ } else if (0 == strcmp(url, "/shards/1ea408fad0213a16f53421e9b72aeb0e12b93a4a")) {
245
+ if (e_count == 0) {
246
+ // mock a flaky farmer w/ truncated bytes
247
+ shard_bytes_sent = shard_bytes_sent / 2;
248
+ page = calloc(shard_bytes_sent + 1, sizeof(char));
249
+ memset(page, 'e', shard_bytes_sent);
250
+ } else {
251
+ page = calloc(shard_bytes + 1, sizeof(char));
252
+ memcpy(page, data + shard_bytes * 4, shard_bytes);
253
+ }
254
+ status_code = MHD_HTTP_OK;
255
+ e_count += 1;
256
+ } else if (0 == strcmp(url, "/shards/0219bb523832c09c77069c74804e5b0476cea7cf")) {
257
+ page = calloc(shard_bytes + 1, sizeof(char));
258
+ memcpy(page, data + shard_bytes * 5, shard_bytes);
259
+ status_code = MHD_HTTP_OK;
260
+ } else if (0 == strcmp(url, "/shards/ebcbe78dd209a03d3ce29f2e5460304de2060031")) {
261
+ page = calloc(shard_bytes + 1, sizeof(char));
262
+ memcpy(page, data + shard_bytes * 6, shard_bytes);
263
+ status_code = MHD_HTTP_OK;
264
+ } else if (0 == strcmp(url, "/shards/5ecd6cc2964a344b42406d3688e13927a51937aa")) {
265
+ page = calloc(shard_bytes + 1, sizeof(char));
266
+ memcpy(page, data + shard_bytes * 7, shard_bytes);
267
+ status_code = MHD_HTTP_OK;
268
+ } else if (0 == strcmp(url, "/shards/88c5e8885160c449b1dbb00ccf317067200b39a0")) {
269
+ page = calloc(shard_bytes + 1, sizeof(char));
270
+ memcpy(page, data + shard_bytes * 8, shard_bytes);
271
+ status_code = MHD_HTTP_OK;
272
+ } else if (0 == strcmp(url, "/shards/76b1a97498e026c47c924374b5b1148543d5c0ab")) {
273
+ page = calloc(shard_bytes + 1, sizeof(char));
274
+ memcpy(page, data + shard_bytes * 9, shard_bytes);
275
+ status_code = MHD_HTTP_OK;
276
+ } else if (0 == strcmp(url, "/shards/48e02627e37433c89fa034d3ee2df644ac7ac7a0")) {
277
+ page = calloc(shard_bytes + 1, sizeof(char));
278
+ memcpy(page, data + shard_bytes * 10, shard_bytes);
279
+ status_code = MHD_HTTP_OK;
280
+ } else if (0 == strcmp(url, "/shards/e4617532be728d48a8155ecfb200d50f00a01a23")) {
281
+ page = calloc(shard_bytes + 1, sizeof(char));
282
+ memcpy(page, data + shard_bytes * 11, shard_bytes);
283
+ status_code = MHD_HTTP_OK;
284
+ } else if (0 == strcmp(url, "/shards/973701b43290e3bef7007db0cb75744f9556ae3b")) {
285
+ page = calloc(shard_bytes + 1, sizeof(char));
286
+ memcpy(page, data + shard_bytes * 12, shard_bytes);
287
+ status_code = MHD_HTTP_OK;
288
+ } else if (0 == strcmp(url, "/shards/a0ec63ad4069fa51a53871c7a282e184371b842b")) {
289
+ page = calloc(shard_bytes + 1, sizeof(char));
290
+ memcpy(page, data + shard_bytes * 13, shard_bytes);
291
+ status_code = MHD_HTTP_OK;
292
+ } else if (0 == strcmp(url, "/shards/424cdf090604317570da38ef7d5b41abea0952df")) {
293
+ // this is parity shard #2, parity shard #1 is missing
294
+ page = calloc(shard_bytes + 1, sizeof(char));
295
+ memcpy(page, data + shard_bytes * 15, shard_bytes);
296
+ status_code = MHD_HTTP_OK;
297
+ } else if (0 == strcmp(url, "/shards/a292c0de26b2a9086473905abb938c7a1c45a9e9")) {
298
+ page = calloc(shard_bytes + 1, sizeof(char));
299
+ memcpy(page, data + shard_bytes * 16, shard_bytes);
300
+ status_code = MHD_HTTP_OK;
301
+ } else if (0 == strcmp(url, "/shards/aca155b4deeac64f2be748e3c434e1f5e9719ef3")) {
302
+ page = calloc(shard_bytes + 1, sizeof(char));
303
+ memcpy(page, data + shard_bytes * 17, shard_bytes);
304
+ status_code = MHD_HTTP_OK;
305
+ } else {
306
+ printf("url: %s\n", url);
307
+ }
308
+
309
+ char *sent_page = NULL;
310
+
311
+ if (page) {
312
+ sent_page = malloc(shard_bytes_sent + 1);
313
+ memcpy(sent_page, page, shard_bytes_sent);
314
+ } else {
315
+ shard_bytes_sent = 9;
316
+ sent_page = calloc(shard_bytes_sent + 1, sizeof(char));
317
+ strcat(sent_page, "Not Found");
318
+ }
319
+
320
+ free(page);
321
+
322
+ response = MHD_create_response_from_buffer(shard_bytes_sent,
323
+ (void *) sent_page,
324
+ MHD_RESPMEM_MUST_FREE);
325
+
326
+ ret = MHD_queue_response(connection, status_code, response);
327
+ if (ret == MHD_NO) {
328
+ fprintf(stderr, "MHD_queue_response ERROR: Bad args were passed " \
329
+ "(e.g. null value), or another error occurred" \
330
+ "(e.g. reply was already sent)\n");
331
+ }
332
+
333
+ MHD_destroy_response(response);
334
+
335
+ return ret;
336
+ }
337
+
338
+ return MHD_NO;
339
+ }
340
+
341
+ struct MHD_Daemon *start_farmer_server()
342
+ {
343
+ return MHD_start_daemon(MHD_USE_SELECT_INTERNALLY,
344
+ 8092,
345
+ NULL,
346
+ NULL,
347
+ &mock_farmer_shard_server,
348
+ NULL,
349
+ MHD_OPTION_NOTIFY_COMPLETED,
350
+ &farmer_request_completed,
351
+ NULL,
352
+ MHD_OPTION_END);
353
+ }
354
+
355
+ void free_farmer_data()
356
+ {
357
+ free(data);
358
+ }
@@ -0,0 +1,41 @@
1
+ #include <microhttpd.h>
2
+ #include <assert.h>
3
+
4
+ #include "../src/storj.h"
5
+ #include "../src/bip39.h"
6
+ #include "../src/utils.h"
7
+ #include "../src/crypto.h"
8
+
9
+ #include "mockbridge.json.h"
10
+ #include "mockbridgeinfo.json.h"
11
+
12
+ #define KRED "\x1B[31m"
13
+ #define KGRN "\x1B[32m"
14
+ #define RESET "\x1B[0m"
15
+
16
+ #define USER "testuser@storj.io"
17
+ #define PASS "dce18e67025a8fd68cab186e196a9f8bcca6c9e4a7ad0be8a6f5e48f3abd1b04"
18
+ #define PASSHASH "83c2db176985cb39d2885b15dc3d2afc020bd886ffee10e954a5848429c03c6d"
19
+
20
+ int mock_bridge_server(void *cls,
21
+ struct MHD_Connection *connection,
22
+ const char *url,
23
+ const char *method,
24
+ const char *version,
25
+ const char *upload_data,
26
+ size_t *upload_data_size,
27
+ void **ptr);
28
+
29
+ int mock_farmer_shard_server(void *cls,
30
+ struct MHD_Connection *connection,
31
+ const char *url,
32
+ const char *method,
33
+ const char *version,
34
+ const char *upload_data,
35
+ size_t *upload_data_size,
36
+ void **ptr);
37
+
38
+ struct MHD_Daemon *start_farmer_server();
39
+ void free_farmer_data();
40
+
41
+ int create_test_file(char *file);
@@ -0,0 +1,1617 @@
1
+ #include "storjtests.h"
2
+
3
+ char *folder;
4
+ int tests_ran = 0;
5
+ int test_status = 0;
6
+
7
+ // setup bridge options to point to mock server
8
+ storj_bridge_options_t bridge_options = {
9
+ .proto = "http",
10
+ .host = "localhost",
11
+ .port = 8091,
12
+ .user = "testuser@storj.io",
13
+ .pass = "dce18e67025a8fd68cab186e196a9f8bcca6c9e4a7ad0be8a6f5e48f3abd1b04"
14
+ };
15
+
16
+ // setup bridge options to point to mock server (with incorrect auth)
17
+ storj_bridge_options_t bridge_options_bad = {
18
+ .proto = "http",
19
+ .host = "localhost",
20
+ .port = 8091,
21
+ .user = "testuser@storj.io",
22
+ .pass = "bad password"
23
+ };
24
+
25
+ storj_encrypt_options_t encrypt_options = {
26
+ .mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
27
+ };
28
+
29
+ storj_http_options_t http_options = {
30
+ .user_agent = "storj-test",
31
+ .low_speed_limit = 0,
32
+ .low_speed_time = 0,
33
+ .timeout = 0
34
+ };
35
+
36
+ storj_log_options_t log_options = {
37
+ .level = 0
38
+ };
39
+
40
+ void fail(char *msg)
41
+ {
42
+ printf("\t" KRED "FAIL" RESET " %s\n", msg);
43
+ tests_ran += 1;
44
+ }
45
+
46
+ void pass(char *msg)
47
+ {
48
+ printf("\t" KGRN "PASS" RESET " %s\n", msg);
49
+ test_status += 1;
50
+ tests_ran += 1;
51
+ }
52
+
53
+
54
+ void check_bridge_get_info(uv_work_t *work_req, int status)
55
+ {
56
+ assert(status == 0);
57
+ json_request_t *req = work_req->data;
58
+ assert(req->handle == NULL);
59
+
60
+ struct json_object* value;
61
+ int success = json_object_object_get_ex(req->response, "info", &value);
62
+ assert(success == 1);
63
+ pass("storj_bridge_get_info");
64
+
65
+ json_object_put(req->response);
66
+ free(req);
67
+ free(work_req);
68
+ }
69
+
70
+ void check_get_buckets(uv_work_t *work_req, int status)
71
+ {
72
+ assert(status == 0);
73
+ get_buckets_request_t *req = work_req->data;
74
+ assert(req->handle == NULL);
75
+ assert(json_object_is_type(req->response, json_type_array) == 1);
76
+
77
+ struct json_object *bucket = json_object_array_get_idx(req->response, 0);
78
+ struct json_object* value;
79
+ int success = json_object_object_get_ex(bucket, "id", &value);
80
+ assert(success == 1);
81
+ pass("storj_bridge_get_buckets");
82
+
83
+ storj_free_get_buckets_request(req);
84
+ free(work_req);
85
+ }
86
+
87
+ void check_get_bucket(uv_work_t *work_req, int status)
88
+ {
89
+ assert(status == 0);
90
+ get_bucket_request_t *req = work_req->data;
91
+ assert(req->handle == NULL);
92
+ assert(req->bucket);
93
+ assert(strcmp(req->bucket->name, "test") == 0);
94
+ assert(req->bucket->decrypted);
95
+
96
+ pass("storj_bridge_get_bucket");
97
+
98
+ storj_free_get_bucket_request(req);
99
+ free(work_req);
100
+ }
101
+
102
+ void check_get_buckets_badauth(uv_work_t *work_req, int status)
103
+ {
104
+ assert(status == 0);
105
+ get_buckets_request_t *req = work_req->data;
106
+ assert(req->handle == NULL);
107
+ assert(req->buckets == NULL);
108
+ assert(req->status_code == 401);
109
+
110
+ pass("storj_bridge_get_buckets_badauth");
111
+
112
+ storj_free_get_buckets_request(req);
113
+ free(work_req);
114
+ }
115
+
116
+ void check_create_bucket(uv_work_t *work_req, int status)
117
+ {
118
+ assert(status == 0);
119
+ create_bucket_request_t *req = work_req->data;
120
+ assert(req->handle == NULL);
121
+
122
+ struct json_object* value;
123
+ int success = json_object_object_get_ex(req->response, "name", &value);
124
+ assert(success == 1);
125
+ assert(json_object_is_type(value, json_type_string) == 1);
126
+
127
+ const char* name = json_object_get_string(value);
128
+ assert(strcmp(name, "backups") == 0);
129
+ pass("storj_bridge_create_bucket");
130
+
131
+ json_object_put(req->response);
132
+ free((char *)req->encrypted_bucket_name);
133
+ free(req->bucket);
134
+ free(req);
135
+ free(work_req);
136
+ }
137
+
138
+ void check_delete_bucket(uv_work_t *work_req, int status)
139
+ {
140
+ assert(status == 0);
141
+ json_request_t *req = work_req->data;
142
+ assert(req->handle == NULL);
143
+ assert(req->response == NULL);
144
+ assert(req->status_code == 204);
145
+
146
+ pass("storj_bridge_delete_bucket");
147
+
148
+ json_object_put(req->response);
149
+ free(req->path);
150
+ free(req);
151
+ free(work_req);
152
+ }
153
+
154
+ void check_list_files(uv_work_t *work_req, int status)
155
+ {
156
+ assert(status == 0);
157
+ list_files_request_t *req = work_req->data;
158
+ assert(req->handle == NULL);
159
+ assert(req->response != NULL);
160
+
161
+ struct json_object *file = json_object_array_get_idx(req->response, 0);
162
+ struct json_object *value;
163
+ int success = json_object_object_get_ex(file, "id", &value);
164
+ assert(success == 1);
165
+ assert(json_object_is_type(value, json_type_string) == 1);
166
+
167
+ const char* id = json_object_get_string(value);
168
+ assert(strcmp(id, "f18b5ca437b1ca3daa14969f") == 0);
169
+
170
+ pass("storj_bridge_list_files");
171
+
172
+ storj_free_list_files_request(req);
173
+ free(work_req);
174
+ }
175
+
176
+ void check_list_files_badauth(uv_work_t *work_req, int status)
177
+ {
178
+ assert(status == 0);
179
+ list_files_request_t *req = work_req->data;
180
+ assert(req->handle == NULL);
181
+ assert(req->response == NULL);
182
+ assert(req->files == NULL);
183
+ assert(req->status_code == 401);
184
+
185
+ pass("storj_bridge_list_files_badauth");
186
+
187
+ storj_free_list_files_request(req);
188
+ free(work_req);
189
+ }
190
+
191
+ void check_bucket_tokens(uv_work_t *work_req, int status)
192
+ {
193
+ assert(status == 0);
194
+ json_request_t *req = work_req->data;
195
+ assert(req->handle == NULL);
196
+
197
+ struct json_object *value;
198
+ int success = json_object_object_get_ex(req->response, "token", &value);
199
+ assert(success == 1);
200
+ assert(json_object_is_type(value, json_type_string) == 1);
201
+
202
+ const char* token = json_object_get_string(value);
203
+
204
+ char *t = "a264e12611ad93b1777e82065f86cfcf088967dba2f15559cea5e140d5339a0e";
205
+
206
+ assert(strcmp(token, t) == 0);
207
+
208
+ pass("storj_bridge_create_bucket_token");
209
+
210
+ json_object_put(req->body);
211
+ json_object_put(req->response);
212
+ free(req->path);
213
+ free(req);
214
+ free(work_req);
215
+ }
216
+
217
+ void check_file_pointers(uv_work_t *work_req, int status)
218
+ {
219
+ assert(status == 0);
220
+ json_request_t *req = work_req->data;
221
+ assert(req->handle == NULL);
222
+ assert(req->response);
223
+
224
+ assert(json_object_is_type(req->response, json_type_array) == 1);
225
+
226
+ struct json_object *bucket = json_object_array_get_idx(req->response, 0);
227
+ struct json_object* value;
228
+ int success = json_object_object_get_ex(bucket, "farmer", &value);
229
+ assert(success == 1);
230
+
231
+ pass("storj_bridge_get_file_pointers");
232
+
233
+ json_object_put(req->response);
234
+ free(req->path);
235
+ free(req);
236
+ free(work_req);
237
+ }
238
+
239
+ void check_resolve_file_progress(double progress,
240
+ uint64_t downloaded_bytes,
241
+ uint64_t total_bytes,
242
+ void *handle)
243
+ {
244
+ assert(handle == NULL);
245
+ if (progress == (double)1) {
246
+ pass("storj_bridge_resolve_file (progress finished)");
247
+ }
248
+
249
+ // TODO check error case
250
+ }
251
+
252
+ void check_resolve_file(int status, FILE *fd, void *handle)
253
+ {
254
+ fclose(fd);
255
+ assert(handle == NULL);
256
+ if (status) {
257
+ fail("storj_bridge_resolve_file");
258
+ printf("Download failed: %s\n", storj_strerror(status));
259
+ } else {
260
+ pass("storj_bridge_resolve_file");
261
+ }
262
+ }
263
+
264
+ void check_resolve_file_cancel(int status, FILE *fd, void *handle)
265
+ {
266
+ fclose(fd);
267
+ assert(handle == NULL);
268
+ if (status == STORJ_TRANSFER_CANCELED) {
269
+ pass("storj_bridge_resolve_file_cancel");
270
+ } else {
271
+ fail("storj_bridge_resolve_file_cancel");
272
+ }
273
+ }
274
+
275
+ void check_store_file_progress(double progress,
276
+ uint64_t uploaded_bytes,
277
+ uint64_t total_bytes,
278
+ void *handle)
279
+ {
280
+ assert(handle == NULL);
281
+ if (progress == (double)1) {
282
+ pass("storj_bridge_store_file (progress finished)");
283
+ }
284
+ }
285
+
286
+ void check_store_file(int error_code, char *file_id, void *handle)
287
+ {
288
+ assert(handle == NULL);
289
+ if (error_code == 0) {
290
+ if (strcmp(file_id, "85fb0ed00de1196dc22e0f6d") == 0 ) {
291
+ pass("storj_bridge_store_file");
292
+ } else {
293
+ fail("storj_bridge_store_file(0)");
294
+ }
295
+ } else {
296
+ fail("storj_bridge_store_file(1)");
297
+ printf("\t\tERROR: %s\n", storj_strerror(error_code));
298
+ }
299
+
300
+ free(file_id);
301
+ }
302
+
303
+ void check_store_file_cancel(int error_code, char *file_id, void *handle)
304
+ {
305
+ assert(handle == NULL);
306
+ if (error_code == STORJ_TRANSFER_CANCELED) {
307
+ pass("storj_bridge_store_file_cancel");
308
+ } else {
309
+ fail("storj_bridge_store_file_cancel");
310
+ printf("\t\tERROR: %s\n", storj_strerror(error_code));
311
+ }
312
+
313
+ free(file_id);
314
+ }
315
+
316
+ void check_delete_file(uv_work_t *work_req, int status)
317
+ {
318
+ assert(status == 0);
319
+ json_request_t *req = work_req->data;
320
+ assert(req->handle == NULL);
321
+ assert(req->response == NULL);
322
+ assert(req->status_code == 200);
323
+
324
+ pass("storj_bridge_delete_file");
325
+
326
+ free(req->path);
327
+ free(req);
328
+ free(work_req);
329
+ }
330
+
331
+ void check_create_frame(uv_work_t *work_req, int status)
332
+ {
333
+ assert(status == 0);
334
+ json_request_t *req = work_req->data;
335
+ assert(req->handle == NULL);
336
+
337
+ struct json_object *value;
338
+ int success = json_object_object_get_ex(req->response, "id", &value);
339
+ assert(success == 1);
340
+ assert(json_object_is_type(value, json_type_string) == 1);
341
+
342
+ const char* id = json_object_get_string(value);
343
+
344
+ assert(strcmp(id, "d6367831f7f1b117ffdd0015") == 0);
345
+ pass("storj_bridge_create_frame");
346
+
347
+ json_object_put(req->response);
348
+ free(req);
349
+ free(work_req);
350
+ }
351
+
352
+ void check_get_frames(uv_work_t *work_req, int status)
353
+ {
354
+ assert(status == 0);
355
+ json_request_t *req = work_req->data;
356
+ assert(req->handle == NULL);
357
+
358
+ struct json_object *file = json_object_array_get_idx(req->response, 0);
359
+ struct json_object *value;
360
+ int success = json_object_object_get_ex(file, "id", &value);
361
+ assert(success == 1);
362
+ assert(json_object_is_type(value, json_type_string) == 1);
363
+
364
+ const char* id = json_object_get_string(value);
365
+ assert(strcmp(id, "52b8cc8dfd47bb057d8c8a17") == 0);
366
+
367
+ pass("storj_bridge_get_frames");
368
+
369
+ json_object_put(req->response);
370
+ free(req);
371
+ free(work_req);
372
+ }
373
+
374
+ void check_get_frame(uv_work_t *work_req, int status)
375
+ {
376
+ assert(status == 0);
377
+ json_request_t *req = work_req->data;
378
+ assert(req->handle == NULL);
379
+
380
+ struct json_object *value;
381
+ int success = json_object_object_get_ex(req->response, "id", &value);
382
+ assert(success == 1);
383
+ assert(json_object_is_type(value, json_type_string) == 1);
384
+
385
+ const char* id = json_object_get_string(value);
386
+
387
+ assert(strcmp(id, "192f90792f42875a7533340b") == 0);
388
+ pass("storj_bridge_get_frame");
389
+
390
+ json_object_put(req->response);
391
+ free(req->path);
392
+ free(req);
393
+ free(work_req);
394
+ }
395
+
396
+ void check_delete_frame(uv_work_t *work_req, int status)
397
+ {
398
+ assert(status == 0);
399
+ json_request_t *req = work_req->data;
400
+ assert(req->handle == NULL);
401
+ assert(req->response == NULL);
402
+ assert(req->status_code == 200);
403
+
404
+ pass("storj_bridge_delete_frame");
405
+
406
+ json_object_put(req->response);
407
+ free(req->path);
408
+ free(req);
409
+ free(work_req);
410
+ }
411
+
412
+ void check_file_info(uv_work_t *work_req, int status)
413
+ {
414
+ assert(status == 0);
415
+ json_request_t *req = work_req->data;
416
+ assert(req->handle == NULL);
417
+
418
+ struct json_object *value;
419
+ int success = json_object_object_get_ex(req->response, "mimetype", &value);
420
+ assert(success == 1);
421
+ assert(json_object_is_type(value, json_type_string) == 1);
422
+
423
+ const char* mimetype = json_object_get_string(value);
424
+
425
+ assert(strcmp(mimetype, "video/ogg") == 0);
426
+ pass("storj_bridge_get_file_info");
427
+
428
+ json_object_put(req->response);
429
+ free(req->path);
430
+ free(req);
431
+ free(work_req);
432
+ }
433
+
434
+ void check_list_mirrors(uv_work_t *work_req, int status)
435
+ {
436
+ assert(status == 0);
437
+ json_request_t *req = work_req->data;
438
+ assert(req->handle == NULL);
439
+
440
+ assert(json_object_is_type(req->response, json_type_array) == 1);
441
+ struct json_object *firstShard = json_object_array_get_idx(req->response,
442
+ 0);
443
+ struct json_object *established;
444
+ struct json_object *available;
445
+ json_object_object_get_ex(firstShard, "established", &established);
446
+ json_object_object_get_ex(firstShard, "available", &available);
447
+ assert(json_object_is_type(established, json_type_array) == 1);
448
+ assert(json_object_is_type(established, json_type_array) == 1);
449
+
450
+ pass("storj_bridge_list_mirrors");
451
+
452
+ json_object_put(req->response);
453
+ free(req->path);
454
+ free(req);
455
+ free(work_req);
456
+ }
457
+
458
+ void check_register(uv_work_t *work_req, int status)
459
+ {
460
+ assert(status == 0);
461
+ json_request_t *req = work_req->data;
462
+ assert(req->handle == NULL);
463
+ assert(req->status_code == 201);
464
+
465
+ struct json_object *value;
466
+ int success = json_object_object_get_ex(req->response, "email", &value);
467
+ assert(success == 1);
468
+ assert(json_object_is_type(value, json_type_string) == 1);
469
+
470
+ const char *email = json_object_get_string(value);
471
+
472
+ assert(strcmp(email, "test@test.com") == 0);
473
+ pass("storj_bridge_register");
474
+
475
+ json_object_put(req->body);
476
+ json_object_put(req->response);
477
+ free(req);
478
+ free(work_req);
479
+ }
480
+
481
+ int create_test_upload_file(char *filepath)
482
+ {
483
+ FILE *fp;
484
+ fp = fopen(filepath, "w+");
485
+
486
+ if (fp == NULL) {
487
+ printf(KRED "Could not create upload file: %s\n" RESET, filepath);
488
+ exit(0);
489
+ }
490
+
491
+ int shard_size = 16777216;
492
+ char *bytes = "abcdefghijklmn";
493
+ for (int i = 0; i < strlen(bytes); i++) {
494
+ char *page = calloc(shard_size + 1, sizeof(char));
495
+ memset(page, bytes[i], shard_size);
496
+ fputs(page, fp);
497
+ free(page);
498
+ }
499
+
500
+ fclose(fp);
501
+ return 0;
502
+ }
503
+
504
+ int test_upload()
505
+ {
506
+
507
+ // initialize event loop and environment
508
+ storj_env_t *env = storj_init_env(&bridge_options,
509
+ &encrypt_options,
510
+ &http_options,
511
+ &log_options);
512
+ assert(env != NULL);
513
+
514
+ char *file_name = "storj-test-upload.data";
515
+ int len = strlen(folder) + strlen(file_name);
516
+ char *file = calloc(len + 1, sizeof(char));
517
+ strcpy(file, folder);
518
+ strcat(file, file_name);
519
+ file[len] = '\0';
520
+
521
+ create_test_upload_file(file);
522
+
523
+ // upload file
524
+ storj_upload_opts_t upload_opts = {
525
+ .index = "d2891da46d9c3bf42ad619ceddc1b6621f83e6cb74e6b6b6bc96bdbfaefb8692",
526
+ .bucket_id = "368be0816766b28fd5f43af5",
527
+ .file_name = file_name,
528
+ .fd = fopen(file, "r"),
529
+ .rs = true
530
+ };
531
+
532
+ storj_upload_state_t *state = storj_bridge_store_file(env,
533
+ &upload_opts,
534
+ NULL,
535
+ check_store_file_progress,
536
+ check_store_file);
537
+ if (!state || state->error_status != 0) {
538
+ return 1;
539
+ }
540
+
541
+ // run all queued events
542
+ if (uv_run(env->loop, UV_RUN_DEFAULT)) {
543
+ return 1;
544
+ }
545
+
546
+ free(file);
547
+ storj_destroy_env(env);
548
+
549
+ return 0;
550
+ }
551
+
552
+ int test_upload_cancel()
553
+ {
554
+
555
+ // initialize event loop and environment
556
+ storj_env_t *env = storj_init_env(&bridge_options,
557
+ &encrypt_options,
558
+ &http_options,
559
+ &log_options);
560
+ assert(env != NULL);
561
+
562
+ char *file_name = "storj-test-upload.data";
563
+ int len = strlen(folder) + strlen(file_name);
564
+ char *file = calloc(len + 1, sizeof(char));
565
+ strcpy(file, folder);
566
+ strcat(file, file_name);
567
+ file[len] = '\0';
568
+
569
+ create_test_upload_file(file);
570
+
571
+ // upload file
572
+ storj_upload_opts_t upload_opts = {
573
+ .index = "d2891da46d9c3bf42ad619ceddc1b6621f83e6cb74e6b6b6bc96bdbfaefb8692",
574
+ .bucket_id = "368be0816766b28fd5f43af5",
575
+ .file_name = file_name,
576
+ .fd = fopen(file, "r")
577
+ };
578
+
579
+ storj_upload_state_t *state = storj_bridge_store_file(env,
580
+ &upload_opts,
581
+ NULL,
582
+ check_store_file_progress,
583
+ check_store_file_cancel);
584
+ if (!state || state->error_status != 0) {
585
+ return 1;
586
+ }
587
+
588
+ // process the loop one at a time so that we can do other things while
589
+ // the loop is processing, such as cancel the download
590
+ int count = 0;
591
+ bool more;
592
+ int status = 0;
593
+ do {
594
+ more = uv_run(env->loop, UV_RUN_ONCE);
595
+ if (more == false) {
596
+ more = uv_loop_alive(env->loop);
597
+ if (uv_run(env->loop, UV_RUN_NOWAIT) != 0) {
598
+ more = true;
599
+ }
600
+ }
601
+
602
+ count++;
603
+
604
+ if (count == 100) {
605
+ status = storj_bridge_store_file_cancel(state);
606
+ assert(status == 0);
607
+ }
608
+
609
+ } while (more == true);
610
+
611
+ free(file);
612
+ storj_destroy_env(env);
613
+
614
+ return 0;
615
+ }
616
+
617
+ int test_download()
618
+ {
619
+
620
+ // initialize event loop and environment
621
+ storj_env_t *env = storj_init_env(&bridge_options,
622
+ &encrypt_options,
623
+ &http_options,
624
+ &log_options);
625
+ assert(env != NULL);
626
+
627
+ // resolve file
628
+ char *download_file = calloc(strlen(folder) + 24 + 1, sizeof(char));
629
+ strcpy(download_file, folder);
630
+ strcat(download_file, "storj-test-download.data");
631
+ FILE *download_fp = fopen(download_file, "w+");
632
+
633
+ char *bucket_id = "368be0816766b28fd5f43af5";
634
+ char *file_id = "998960317b6725a3f8080c2b";
635
+
636
+ storj_download_state_t *state = storj_bridge_resolve_file(env,
637
+ bucket_id,
638
+ file_id,
639
+ download_fp,
640
+ NULL,
641
+ check_resolve_file_progress,
642
+ check_resolve_file);
643
+
644
+ if (!state || state->error_status != 0) {
645
+ return 1;
646
+ }
647
+
648
+ free(download_file);
649
+
650
+ if (uv_run(env->loop, UV_RUN_DEFAULT)) {
651
+ return 1;
652
+ }
653
+
654
+ storj_destroy_env(env);
655
+
656
+ return 0;
657
+ }
658
+
659
+ int test_download_cancel()
660
+ {
661
+
662
+ // initialize event loop and environment
663
+ storj_env_t *env = storj_init_env(&bridge_options,
664
+ &encrypt_options,
665
+ &http_options,
666
+ &log_options);
667
+ assert(env != NULL);
668
+
669
+ // resolve file
670
+ char *download_file = calloc(strlen(folder) + 33 + 1, sizeof(char));
671
+ strcpy(download_file, folder);
672
+ strcat(download_file, "storj-test-download-canceled.data");
673
+ FILE *download_fp = fopen(download_file, "w+");
674
+
675
+ char *bucket_id = "368be0816766b28fd5f43af5";
676
+ char *file_id = "998960317b6725a3f8080c2b";
677
+
678
+ storj_download_state_t *state = storj_bridge_resolve_file(env,
679
+ bucket_id,
680
+ file_id,
681
+ download_fp,
682
+ NULL,
683
+ check_resolve_file_progress,
684
+ check_resolve_file_cancel);
685
+
686
+ if (!state || state->error_status != 0) {
687
+ return 1;
688
+ }
689
+
690
+ // process the loop one at a time so that we can do other things while
691
+ // the loop is processing, such as cancel the download
692
+ int count = 0;
693
+ bool more;
694
+ int status = 0;
695
+ do {
696
+ more = uv_run(env->loop, UV_RUN_ONCE);
697
+ if (more == false) {
698
+ more = uv_loop_alive(env->loop);
699
+ if (uv_run(env->loop, UV_RUN_NOWAIT) != 0) {
700
+ more = true;
701
+ }
702
+ }
703
+
704
+ count++;
705
+
706
+ if (count == 100) {
707
+ status = storj_bridge_resolve_file_cancel(state);
708
+ assert(status == 0);
709
+ }
710
+
711
+ } while (more == true);
712
+
713
+
714
+ free(download_file);
715
+ storj_destroy_env(env);
716
+
717
+ return 0;
718
+ }
719
+
720
+ int test_api_badauth()
721
+ {
722
+ // initialize event loop and environment
723
+ storj_env_t *env = storj_init_env(&bridge_options_bad,
724
+ &encrypt_options,
725
+ &http_options,
726
+ &log_options);
727
+
728
+ assert(env != NULL);
729
+
730
+ int status = 0;
731
+
732
+ // get buckets
733
+ status = storj_bridge_get_buckets(env, NULL, check_get_buckets_badauth);
734
+ assert(status == 0);
735
+
736
+ char *bucket_id = "368be0816766b28fd5f43af5";
737
+
738
+ // list files in a bucket
739
+ status = storj_bridge_list_files(env, bucket_id, NULL,
740
+ check_list_files_badauth);
741
+ assert(status == 0);
742
+
743
+ // run all queued events
744
+ if (uv_run(env->loop, UV_RUN_DEFAULT)) {
745
+ return 1;
746
+ }
747
+
748
+ storj_destroy_env(env);
749
+
750
+ return 0;
751
+ }
752
+
753
+ int test_api()
754
+ {
755
+ // initialize event loop and environment
756
+ storj_env_t *env = storj_init_env(&bridge_options,
757
+ &encrypt_options,
758
+ &http_options,
759
+ &log_options);
760
+ assert(env != NULL);
761
+
762
+ int status;
763
+
764
+ // get general api info
765
+ status = storj_bridge_get_info(env, NULL, check_bridge_get_info);
766
+ assert(status == 0);
767
+
768
+ // get buckets
769
+ status = storj_bridge_get_buckets(env, NULL, check_get_buckets);
770
+ assert(status == 0);
771
+
772
+ char *bucket_id = "368be0816766b28fd5f43af5";
773
+
774
+ // get bucket
775
+ status = storj_bridge_get_bucket(env, bucket_id, NULL, check_get_bucket);
776
+ assert(status == 0);
777
+
778
+ // create a new bucket with a name
779
+ status = storj_bridge_create_bucket(env, "backups", NULL,
780
+ check_create_bucket);
781
+ assert(status == 0);
782
+
783
+ // delete a bucket
784
+ // TODO check for successful status code, response has object
785
+ status = storj_bridge_delete_bucket(env, bucket_id, NULL,
786
+ check_delete_bucket);
787
+ assert(status == 0);
788
+
789
+ // list files in a bucket
790
+ status = storj_bridge_list_files(env, bucket_id, NULL,
791
+ check_list_files);
792
+ assert(status == 0);
793
+
794
+ // create bucket tokens
795
+ status = storj_bridge_create_bucket_token(env,
796
+ bucket_id,
797
+ BUCKET_PUSH,
798
+ NULL,
799
+ check_bucket_tokens);
800
+ assert(status == 0);
801
+
802
+ char *file_id = "998960317b6725a3f8080c2b";
803
+
804
+ // delete a file in a bucket
805
+ status = storj_bridge_delete_file(env,
806
+ bucket_id,
807
+ file_id,
808
+ NULL,
809
+ check_delete_file);
810
+ assert(status == 0);
811
+
812
+ // create a file frame
813
+ status = storj_bridge_create_frame(env, NULL, check_create_frame);
814
+ assert(status == 0);
815
+
816
+ // get frames
817
+ status = storj_bridge_get_frames(env, NULL, check_get_frames);
818
+ assert(status == 0);
819
+
820
+ char *frame_id = "d4af71ab00e15b0c1a7b6ab2";
821
+
822
+ // get frame
823
+ status = storj_bridge_get_frame(env, frame_id, NULL, check_get_frame);
824
+ assert(status == 0);
825
+
826
+ // delete frame
827
+ status = storj_bridge_delete_frame(env, frame_id, NULL, check_delete_frame);
828
+ assert(status == 0);
829
+
830
+ // get file information
831
+ status = storj_bridge_get_file_info(env, bucket_id,
832
+ file_id, NULL, check_file_info);
833
+ assert(status == 0);
834
+
835
+ // get file pointers
836
+ status = storj_bridge_get_file_pointers(env, bucket_id,
837
+ file_id, NULL, check_file_pointers);
838
+ assert(status == 0);
839
+
840
+ // get mirrors
841
+ status = storj_bridge_list_mirrors(env, bucket_id, file_id, NULL,
842
+ check_list_mirrors);
843
+ assert(status == 0);
844
+
845
+ // register a user
846
+ status = storj_bridge_register(env, "testuser@test.com", "asdf", NULL,
847
+ check_register);
848
+ assert(status == 0);
849
+
850
+ // run all queued events
851
+ if (uv_run(env->loop, UV_RUN_DEFAULT)) {
852
+ return 1;
853
+ }
854
+
855
+ storj_destroy_env(env);
856
+
857
+ return 0;
858
+ }
859
+
860
+
861
+ int test_mnemonic_check()
862
+ {
863
+ static const char *vectors_ok[] = {
864
+ "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
865
+ "legal winner thank year wave sausage worth useful legal winner thank yellow",
866
+ "letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
867
+ "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
868
+ "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
869
+ "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
870
+ "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
871
+ "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
872
+ "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
873
+ "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
874
+ "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
875
+ "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
876
+ "jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge",
877
+ "renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
878
+ "dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
879
+ "afford alter spike radar gate glance object seek swamp infant panel yellow",
880
+ "indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
881
+ "clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
882
+ "turtle front uncle idea crush write shrug there lottery flower risk shell",
883
+ "kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
884
+ "exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
885
+ "board flee heavy tunnel powder denial science ski answer betray cargo cat",
886
+ "board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
887
+ "beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
888
+ 0,
889
+ };
890
+ static const char *vectors_fail[] = {
891
+ "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
892
+ "above winner thank year wave sausage worth useful legal winner thank yellow",
893
+ "above advice cage absurd amount doctor acoustic avoid letter advice cage above",
894
+ "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
895
+ "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
896
+ "above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
897
+ "above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
898
+ "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
899
+ "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
900
+ "above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
901
+ "above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
902
+ "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
903
+ "above better achieve collect unaware mountain thought cargo oxygen act hood bridge",
904
+ "above stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
905
+ "above pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
906
+ "above alter spike radar gate glance object seek swamp infant panel yellow",
907
+ "above race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
908
+ "above control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
909
+ "above front uncle idea crush write shrug there lottery flower risk shell",
910
+ "above carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
911
+ "above ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
912
+ "above flee heavy tunnel powder denial science ski answer betray cargo cat",
913
+ "above blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
914
+ "above stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
915
+ "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
916
+ "winner thank year wave sausage worth useful legal winner thank yellow",
917
+ "advice cage absurd amount doctor acoustic avoid letter advice cage above",
918
+ "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
919
+ "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
920
+ "winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
921
+ "advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
922
+ "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
923
+ "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
924
+ "winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
925
+ "advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
926
+ "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
927
+ "better achieve collect unaware mountain thought cargo oxygen act hood bridge",
928
+ "stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
929
+ "pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
930
+ "alter spike radar gate glance object seek swamp infant panel yellow",
931
+ "race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
932
+ "control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
933
+ "front uncle idea crush write shrug there lottery flower risk shell",
934
+ "carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
935
+ "ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
936
+ "flee heavy tunnel powder denial science ski answer betray cargo cat",
937
+ "blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
938
+ "stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
939
+ 0,
940
+ };
941
+
942
+ const char **m;
943
+ int r;
944
+ int r2;
945
+ m = vectors_ok;
946
+ while (*m) {
947
+ r = mnemonic_check(*m);
948
+ r2 = storj_mnemonic_check(*m);
949
+ assert(r == 1);
950
+ assert(r2 == 1);
951
+ m++;
952
+ }
953
+ m = vectors_fail;
954
+ while (*m) {
955
+ r = mnemonic_check(*m);
956
+ r2 = mnemonic_check(*m);
957
+ assert(r == 0);
958
+ assert(r2 == 0);
959
+ m++;
960
+ }
961
+
962
+ pass("mnemonic_check");
963
+
964
+ return 0;
965
+ }
966
+
967
+ int test_storj_mnemonic_generate_256()
968
+ {
969
+ int status;
970
+ int stren = 256;
971
+ char *mnemonic = NULL;
972
+ storj_mnemonic_generate(stren, &mnemonic);
973
+ status = storj_mnemonic_check(mnemonic);
974
+
975
+ if (status != 1) {
976
+ fail("test_mnemonic_generate");
977
+ printf("\t\texpected mnemonic check: %i\n", 0);
978
+ printf("\t\tactual mnemonic check: %i\n", status);
979
+ free(mnemonic);
980
+ return 1;
981
+ }
982
+ free(mnemonic);
983
+
984
+ pass("test_storj_mnemonic_check_256");
985
+
986
+ return 0;
987
+ }
988
+
989
+ int test_storj_mnemonic_generate()
990
+ {
991
+ int status;
992
+ int stren = 128;
993
+ char *mnemonic = NULL;
994
+ storj_mnemonic_generate(stren, &mnemonic);
995
+ status = storj_mnemonic_check(mnemonic);
996
+
997
+ if (status != 1) {
998
+ fail("test_mnemonic_generate");
999
+ printf("\t\texpected mnemonic check: %i\n", 0);
1000
+ printf("\t\tactual mnemonic check: %i\n", status);
1001
+ free(mnemonic);
1002
+ return 1;
1003
+ }
1004
+ free(mnemonic);
1005
+
1006
+ pass("test_storj_mnemonic_check");
1007
+
1008
+ return 0;
1009
+ }
1010
+
1011
+ int test_mnemonic_generate()
1012
+ {
1013
+ int status;
1014
+ int stren = 128;
1015
+ char *mnemonic = NULL;
1016
+ mnemonic_generate(stren, &mnemonic);
1017
+ status = mnemonic_check(mnemonic);
1018
+
1019
+ if (status != 1) {
1020
+ fail("test_mnemonic_generate");
1021
+ printf("\t\texpected mnemonic check: %i\n", 0);
1022
+ printf("\t\tactual mnemonic check: %i\n", status);
1023
+ free(mnemonic);
1024
+ return 1;
1025
+ }
1026
+ free(mnemonic);
1027
+
1028
+ pass("test_mnemonic_check");
1029
+
1030
+ return 0;
1031
+ }
1032
+
1033
+ int test_generate_seed()
1034
+ {
1035
+ char *mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
1036
+ char *seed = calloc(128 + 1, sizeof(char));
1037
+ char *expected_seed = "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4";
1038
+
1039
+ mnemonic_to_seed(mnemonic, "", &seed);
1040
+ seed[128] = '\0';
1041
+
1042
+ int check = memcmp(seed, expected_seed, 128);
1043
+ if (check != 0) {
1044
+ fail("test_generate_seed");
1045
+ printf("\t\texpected seed: %s\n", expected_seed);
1046
+ printf("\t\tactual seed: %s\n", seed);
1047
+
1048
+ free(seed);
1049
+ return 1;
1050
+ }
1051
+
1052
+ free(seed);
1053
+ pass("test_generate_seed");
1054
+
1055
+ return 0;
1056
+ }
1057
+
1058
+ int test_generate_seed_256()
1059
+ {
1060
+ char *mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art";
1061
+ char *seed = calloc(128 + 1, sizeof(char));
1062
+ char *expected_seed = "408b285c123836004f4b8842c89324c1f01382450c0d439af345ba7fc49acf705489c6fc77dbd4e3dc1dd8cc6bc9f043db8ada1e243c4a0eafb290d399480840";
1063
+
1064
+ mnemonic_to_seed(mnemonic, "", &seed);
1065
+ seed[128] = '\0';
1066
+
1067
+ int check = memcmp(seed, expected_seed, 128);
1068
+ if (check != 0) {
1069
+ fail("test_generate_seed_256");
1070
+ printf("\t\texpected seed: %s\n", expected_seed);
1071
+ printf("\t\tactual seed: %s\n", seed);
1072
+
1073
+ free(seed);
1074
+ return 1;
1075
+ }
1076
+
1077
+ free(seed);
1078
+ pass("test_generate_seed_256");
1079
+
1080
+ return 0;
1081
+ }
1082
+
1083
+
1084
+ int test_generate_seed_256_trezor()
1085
+ {
1086
+ char *mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art";
1087
+ char *seed = calloc(128 + 1, sizeof(char));
1088
+ char *expected_seed = "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8";
1089
+
1090
+ mnemonic_to_seed(mnemonic, "TREZOR", &seed);
1091
+ seed[128] = '\0';
1092
+
1093
+ int check = memcmp(seed, expected_seed, 128);
1094
+ if (check != 0) {
1095
+ fail("test_generate_seed_256_trezor");
1096
+ printf("\t\texpected seed: %s\n", expected_seed);
1097
+ printf("\t\tactual seed: %s\n", seed);
1098
+
1099
+ free(seed);
1100
+ return 1;
1101
+ }
1102
+
1103
+ free(seed);
1104
+ pass("test_generate_seed_256_trezor");
1105
+
1106
+ return 0;
1107
+ }
1108
+
1109
+ int test_generate_bucket_key()
1110
+ {
1111
+ char *mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
1112
+ char *bucket_id = "0123456789ab0123456789ab";
1113
+ char *bucket_key = calloc(DETERMINISTIC_KEY_SIZE + 1, sizeof(char));
1114
+ char *expected_bucket_key = "b2464469e364834ad21e24c64f637c39083af5067693605c84e259447644f6f6";
1115
+
1116
+ generate_bucket_key(mnemonic, bucket_id, &bucket_key);
1117
+ bucket_key[DETERMINISTIC_KEY_SIZE] = '\0';
1118
+
1119
+ int check = memcmp(expected_bucket_key, bucket_key, DETERMINISTIC_KEY_SIZE);
1120
+ if (check != 0) {
1121
+ fail("test_generate_bucket_key");
1122
+ printf("\t\texpected bucket_key: %s\n", expected_bucket_key);
1123
+ printf("\t\tactual bucket_key: %s\n", bucket_key);
1124
+
1125
+ free(bucket_key);
1126
+ return 1;
1127
+ }
1128
+
1129
+ free(bucket_key);
1130
+ pass("test_generate_bucket_key");
1131
+
1132
+ return 0;
1133
+ }
1134
+
1135
+ int test_generate_file_key()
1136
+ {
1137
+ char *mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
1138
+ char *bucket_id = "0123456789ab0123456789ab";
1139
+ char *file_name = "samplefile.txt";
1140
+ char *index = "150589c9593bbebc0e795d8c4fa97304b42c110d9f0095abfac644763beca66e";
1141
+ char *file_key = calloc(DETERMINISTIC_KEY_SIZE + 1, sizeof(char));
1142
+ char *expected_file_key = "bb3552fc2e16d24a147af4b2d163e3164e6dbd04bbc45fc1c3eab69f384337e9";
1143
+
1144
+ generate_file_key(mnemonic, bucket_id, index, &file_key);
1145
+
1146
+ int check = strcmp(expected_file_key, file_key);
1147
+ if (check != 0) {
1148
+ fail("test_generate_file_key");
1149
+ printf("\t\texpected file_key: %s\n", expected_file_key);
1150
+ printf("\t\tactual file_key: %s\n", file_key);
1151
+
1152
+ free(file_key);
1153
+ return 1;
1154
+ }
1155
+
1156
+ free(file_key);
1157
+ pass("test_generate_file_key");
1158
+
1159
+ return 0;
1160
+ }
1161
+
1162
+ int test_str2hex()
1163
+ {
1164
+ char *data = "632442ba2e5f28a3a4e68dcb0b45d1d8f097d5b47479d74e2259055aa25a08aa";
1165
+
1166
+ uint8_t *buffer = str2hex(64, data);
1167
+
1168
+ uint8_t expected[32] = {99,36,66,186,46,95,40,163,164,230,141,203,11,69,
1169
+ 209,216,240,151,213,180,116,121,215,78,34,89,5,
1170
+ 90,162,90,8,170};
1171
+
1172
+ int failed = 0;
1173
+ for (int i = 0; i < 32; i++) {
1174
+ if (expected[i] != buffer[i]) {
1175
+ failed = 1;
1176
+ }
1177
+ }
1178
+
1179
+ if (failed) {
1180
+ fail("test_str2hex");
1181
+ } else {
1182
+ pass("test_str2hex");
1183
+ }
1184
+
1185
+ free(buffer);
1186
+
1187
+ return 0;
1188
+ }
1189
+
1190
+ int test_hex2str()
1191
+ {
1192
+ uint8_t data[32] = {99,36,66,186,46,95,40,163,164,230,141,203,11,69,
1193
+ 209,216,240,151,213,180,116,121,215,78,34,89,5,
1194
+ 90,162,90,8,170};
1195
+
1196
+ char *result = hex2str(32, data);
1197
+ if (!result) {
1198
+ fail("test_hex2str");
1199
+ return 0;
1200
+ }
1201
+
1202
+ char *expected = "632442ba2e5f28a3a4e68dcb0b45d1d8f097d5b47479d74e2259055aa25a08aa";
1203
+
1204
+ int failed = 0;
1205
+ if (strcmp(expected, result) != 0) {
1206
+ failed = 1;
1207
+ }
1208
+
1209
+ if (failed) {
1210
+ fail("test_hex2str");
1211
+ } else {
1212
+ pass("test_hex2str");
1213
+ }
1214
+
1215
+ free(result);
1216
+
1217
+ return 0;
1218
+ }
1219
+
1220
+ int test_get_time_milliseconds()
1221
+ {
1222
+ double time = get_time_milliseconds();
1223
+
1224
+ // TODO check against another source
1225
+ if (time) {
1226
+ pass("test_get_time_milliseconds");
1227
+ } else {
1228
+ fail("test_get_time_milliseconds");
1229
+ }
1230
+
1231
+ return 0;
1232
+ }
1233
+
1234
+ int test_determine_shard_size()
1235
+ {
1236
+ uint64_t file_size;
1237
+ uint64_t shard_size;
1238
+ uint64_t expected_shard_size;
1239
+
1240
+ // 1000 bytes should be 8Mb
1241
+ file_size = 1000;
1242
+ expected_shard_size = 2097152;
1243
+ shard_size = determine_shard_size(file_size, 0);
1244
+
1245
+ if (shard_size != expected_shard_size) {
1246
+ fail("test_determine_shard_size");
1247
+ printf("\t\texpected shard_size: %" PRIu64 "\n", expected_shard_size);
1248
+ printf("\t\tactual shard_size: %" PRIu64 "\n", shard_size);
1249
+
1250
+ return 1;
1251
+ }
1252
+
1253
+ file_size = 134217729;
1254
+ expected_shard_size = 16777216;
1255
+ shard_size = determine_shard_size(file_size, 0);
1256
+
1257
+ if (shard_size != expected_shard_size) {
1258
+ fail("test_determine_shard_size");
1259
+ printf("\t\texpected shard_size: %" PRIu64 "\n", expected_shard_size);
1260
+ printf("\t\tactual shard_size: %" PRIu64 "\n", shard_size);
1261
+
1262
+ return 1;
1263
+ }
1264
+
1265
+ file_size = 268435457;
1266
+ expected_shard_size = 33554432;
1267
+ shard_size = determine_shard_size(file_size, 0);
1268
+
1269
+ if (shard_size != expected_shard_size) {
1270
+ fail("test_determine_shard_size");
1271
+ printf("\t\texpected shard_size: %" PRIu64 "\n", expected_shard_size);
1272
+ printf("\t\tactual shard_size: %" PRIu64 "\n", shard_size);
1273
+
1274
+ return 1;
1275
+ }
1276
+
1277
+ // Make sure we stop at max file size
1278
+ file_size = 1012001737418240;
1279
+ expected_shard_size = 4294967296;
1280
+ shard_size = determine_shard_size(file_size, 0);
1281
+
1282
+ if (shard_size != expected_shard_size) {
1283
+ fail("test_determine_shard_size");
1284
+ printf("\t\texpected shard_size: %" PRIu64 "\n", expected_shard_size);
1285
+ printf("\t\tactual shard_size: %" PRIu64 "\n", shard_size);
1286
+
1287
+ return 1;
1288
+ }
1289
+
1290
+ // Test fail case
1291
+ file_size = 0;
1292
+ expected_shard_size = 0;
1293
+ shard_size = determine_shard_size(file_size, 0);
1294
+
1295
+ if (shard_size != expected_shard_size) {
1296
+ fail("test_determine_shard_size");
1297
+ printf("\t\texpected shard_size: %" PRIu64 "\n", expected_shard_size);
1298
+ printf("\t\tactual shard_size: %" PRIu64 "\n", shard_size);
1299
+
1300
+ return 1;
1301
+ }
1302
+
1303
+ pass("test_determine_shard_size");
1304
+
1305
+ return 0;
1306
+ }
1307
+
1308
+ int test_increment_ctr_aes_iv()
1309
+ {
1310
+ uint8_t iv[16] = {188,14,95,229,78,112,182,107,
1311
+ 34,206,248,225,52,22,16,183};
1312
+
1313
+ if (!increment_ctr_aes_iv(iv, 1)) {
1314
+ fail("increment_ctr_aes_iv(0)");
1315
+ return 1;
1316
+ }
1317
+
1318
+ if (increment_ctr_aes_iv(iv, AES_BLOCK_SIZE)) {
1319
+ fail("increment_ctr_aes_iv(1)");
1320
+ return 1;
1321
+ }
1322
+
1323
+ if (iv[15] != 184) {
1324
+ fail("increment_ctr_aes_iv(2)");
1325
+ return 1;
1326
+ }
1327
+
1328
+ if (increment_ctr_aes_iv(iv, AES_BLOCK_SIZE * 72)) {
1329
+ fail("increment_ctr_aes_iv(3)");
1330
+ return 1;
1331
+ }
1332
+
1333
+ if (iv[15] != 0 || iv[14] != 17) {
1334
+ fail("increment_ctr_aes_iv(4)");
1335
+ return 1;
1336
+ }
1337
+
1338
+ pass("increment_ctr_aes_iv");
1339
+ return 0;
1340
+ }
1341
+
1342
+ int test_read_write_encrypted_file()
1343
+ {
1344
+ // it should create file passed in if it does not exist
1345
+ char test_file[1024];
1346
+ strcpy(test_file, folder);
1347
+ strcat(test_file, "storj-test-user.json");
1348
+ if (access(test_file, F_OK) != -1) {
1349
+ unlink(test_file);
1350
+ }
1351
+
1352
+ // it should successfully encrypt and decrypt a file with the provided key and salt
1353
+ char *expected_mnemonic = "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless";
1354
+ storj_encrypt_write_auth(test_file, "testpass",
1355
+ "testuser@storj.io", "bridgepass", expected_mnemonic);
1356
+
1357
+ char *bridge_user = NULL;
1358
+ char *bridge_pass = NULL;
1359
+ char *mnemonic = NULL;
1360
+ if (storj_decrypt_read_auth(test_file, "testpass",
1361
+ &bridge_user, &bridge_pass, &mnemonic)) {
1362
+ fail("test_storj_write_read_auth(0)");
1363
+ return 1;
1364
+ }
1365
+
1366
+ if (strcmp(bridge_user, "testuser@storj.io") != 0) {
1367
+ fail("test_storj_write_read_auth(1)");
1368
+ return 1;
1369
+ }
1370
+
1371
+ if (strcmp(bridge_pass, "bridgepass") != 0) {
1372
+ fail("test_storj_write_read_auth(2)");
1373
+ return 1;
1374
+ }
1375
+
1376
+ if (strcmp(mnemonic, expected_mnemonic) != 0) {
1377
+ fail("test_storj_write_read_auth(3)");
1378
+ return 1;
1379
+ }
1380
+
1381
+ free(bridge_user);
1382
+ free(bridge_pass);
1383
+ free(mnemonic);
1384
+
1385
+ // it should fail to decrypt if the wrong password
1386
+ if (!storj_decrypt_read_auth(test_file, "wrongpass",
1387
+ &bridge_user, &bridge_pass, &mnemonic)) {
1388
+ fail("test_storj_write_read_auth(4)");
1389
+ return 1;
1390
+ }
1391
+
1392
+ free(bridge_user);
1393
+ free(bridge_pass);
1394
+
1395
+ pass("test_storj_write_read_auth");
1396
+
1397
+ return 0;
1398
+ }
1399
+
1400
+ int test_meta_encryption_name(char *filename)
1401
+ {
1402
+
1403
+ uint8_t encrypt_key[32] = {215,99,0,133,172,219,64,35,54,53,171,23,146,160,
1404
+ 81,126,137,21,253,171,48,217,184,188,8,137,3,
1405
+ 4,83,50,30,251};
1406
+ uint8_t iv[32] = {70,219,247,135,162,7,93,193,44,123,188,234,203,115,129,
1407
+ 82,70,219,247,135,162,7,93,193,44,123,188,234,203,115,
1408
+ 129,82};
1409
+
1410
+ char *buffer = NULL;
1411
+ encrypt_meta(filename, encrypt_key, iv, &buffer);
1412
+
1413
+ char *buffer2 = NULL;
1414
+ int status = decrypt_meta(buffer, encrypt_key, &buffer2);
1415
+ if (status != 0) {
1416
+ return 1;
1417
+ }
1418
+
1419
+ if (strcmp(filename, buffer2) != 0) {
1420
+ return 1;
1421
+ }
1422
+
1423
+ free(buffer);
1424
+ free(buffer2);
1425
+
1426
+ return 0;
1427
+ }
1428
+
1429
+ int test_meta_encryption()
1430
+ {
1431
+ for (int i = 1; i < 24; i++) {
1432
+ char *filename = calloc(i + 1, sizeof(char));
1433
+ memset(filename, 'a', i);
1434
+ if (test_meta_encryption_name(filename)) {
1435
+ fail("test_meta_encryption");
1436
+ printf("Failed with filename: %s\n", filename);
1437
+ return 1;
1438
+ }
1439
+ free(filename);
1440
+ }
1441
+ pass("test_meta_encryption");
1442
+ return 0;
1443
+ }
1444
+
1445
+ int test_memory_mapping()
1446
+ {
1447
+
1448
+ char *file_name = "storj-memory-map.data";
1449
+ int len = strlen(folder) + strlen(file_name);
1450
+ char *file = calloc(len + 1, sizeof(char));
1451
+ strcpy(file, folder);
1452
+ strcat(file, file_name);
1453
+ file[len] = '\0';
1454
+
1455
+ create_test_upload_file(file);
1456
+
1457
+ FILE *fp = fopen(file, "r+");
1458
+ int fd = fileno(fp);
1459
+
1460
+ if (!fp) {
1461
+ printf("failed open.\n");
1462
+ return 1;
1463
+ }
1464
+
1465
+ fseek(fp, 0L, SEEK_END);
1466
+ uint64_t filesize = ftell(fp);
1467
+ rewind(fp);
1468
+
1469
+ uint8_t *map = NULL;
1470
+ int error = map_file(fd, filesize, &map, false);
1471
+ if (error) {
1472
+ printf("failed to map file: %i\n", error);
1473
+ fail("test_memory_mapping(0)");
1474
+ return 1;
1475
+ }
1476
+
1477
+ if (map[40001] != 97) {
1478
+ fail("test_memory_mapping(1)");
1479
+ }
1480
+
1481
+ map[40001] = 0;
1482
+
1483
+ error = unmap_file(map, filesize);
1484
+ if (error) {
1485
+ printf("failed to unmap file: %d", error);
1486
+ fail("test_memory_mapping(2)");
1487
+ return 1;
1488
+ }
1489
+
1490
+ fclose(fp);
1491
+
1492
+ FILE *fp2 = fopen(file, "r+");
1493
+ int fd2 = fileno(fp2);
1494
+
1495
+ if (!fp2) {
1496
+ printf("failed open.\n");
1497
+ return 1;
1498
+ }
1499
+
1500
+ uint8_t *map2 = NULL;
1501
+ error = map_file(fd2, filesize, &map2, false);
1502
+ if (error) {
1503
+ printf("failed to map file: %i\n", error);
1504
+ fail("test_memory_mapping(3)");
1505
+ return 1;
1506
+ }
1507
+
1508
+ if (map2[40001] != 0) {
1509
+ fail("test_memory_mapping(4)");
1510
+ }
1511
+
1512
+ error = unmap_file(map2, filesize);
1513
+ if (error) {
1514
+ printf("failed to unmap file: %d", error);
1515
+ fail("test_memory_mapping(5)");
1516
+ return error;
1517
+ }
1518
+
1519
+ fclose(fp2);
1520
+ free(file);
1521
+
1522
+ pass("test_memory_mapping");
1523
+
1524
+ return 0;
1525
+ }
1526
+
1527
+ // Test Bridge Server
1528
+ struct MHD_Daemon *start_test_server()
1529
+ {
1530
+ // spin up test bridge server
1531
+ return MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION,
1532
+ 8091,
1533
+ NULL,
1534
+ NULL,
1535
+ &mock_bridge_server,
1536
+ NULL,
1537
+ MHD_OPTION_END);
1538
+ }
1539
+
1540
+ int main(void)
1541
+ {
1542
+ // Make sure we have a tmp folder
1543
+ folder = getenv("TMPDIR");
1544
+
1545
+ if (folder == 0) {
1546
+ printf("You need to set $TMPDIR before running. (e.g. export TMPDIR=/tmp/)\n");
1547
+ exit(1);
1548
+ }
1549
+
1550
+ // spin up test bridge server
1551
+ struct MHD_Daemon *d = start_test_server();
1552
+ if (d == NULL) {
1553
+ printf("Could not start test server.\n");
1554
+ return 0;
1555
+ };
1556
+
1557
+ // spin up test farmer server
1558
+ struct MHD_Daemon *f = start_farmer_server();
1559
+
1560
+ printf("Test Suite: API\n");
1561
+ test_api();
1562
+ test_api_badauth();
1563
+ printf("\n");
1564
+
1565
+ printf("Test Suite: Uploads\n");
1566
+ test_upload();
1567
+ test_upload_cancel();
1568
+ printf("\n");
1569
+
1570
+ printf("Test Suite: Downloads\n");
1571
+ test_download();
1572
+ test_download_cancel();
1573
+ printf("\n");
1574
+
1575
+ printf("Test Suite: BIP39\n");
1576
+ test_mnemonic_check();
1577
+ test_mnemonic_generate();
1578
+ test_storj_mnemonic_generate();
1579
+ test_storj_mnemonic_generate_256();
1580
+ test_generate_seed();
1581
+ test_generate_seed_256();
1582
+ test_generate_seed_256_trezor();
1583
+ printf("\n");
1584
+
1585
+ printf("Test Suite: Crypto\n");
1586
+ test_generate_bucket_key();
1587
+ test_generate_file_key();
1588
+ test_increment_ctr_aes_iv();
1589
+ test_read_write_encrypted_file();
1590
+ test_meta_encryption();
1591
+ printf("\n");
1592
+
1593
+ printf("Test Suite: Utils\n");
1594
+ test_str2hex();
1595
+ test_hex2str();
1596
+ test_get_time_milliseconds();
1597
+ test_determine_shard_size();
1598
+ test_memory_mapping();
1599
+
1600
+ int num_failed = tests_ran - test_status;
1601
+ printf(KGRN "\nPASSED: %i" RESET, test_status);
1602
+ if (num_failed > 0) {
1603
+ printf(KRED " FAILED: %i" RESET, num_failed);
1604
+ }
1605
+ printf(" TOTAL: %i\n", (tests_ran));
1606
+
1607
+ // Shutdown test servers
1608
+ MHD_stop_daemon(d);
1609
+ MHD_stop_daemon(f);
1610
+ free_farmer_data();
1611
+
1612
+ if (num_failed > 0) {
1613
+ return 1;
1614
+ }
1615
+
1616
+ return 0;
1617
+ }