Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / erasure-code / TestErasureCodeShec.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2014,2015 FUJITSU LIMITED
7  *
8  * Author: Shotaro Kawaguchi <kawaguchi.s@jp.fujitsu.com>
9  * Author: Takanori Nakao <nakao.takanori@jp.fujitsu.com>
10  * Author: Takeshi Miyamae <miyamae.takeshi@jp.fujitsu.com>
11  *
12  *  This library is free software; you can redistribute it and/or
13  *  modify it under the terms of the GNU Lesser General Public
14  *  License as published by the Free Software Foundation; either
15  *  version 2.1 of the License, or (at your option) any later version.
16  *
17  */
18
19 //SUMMARY: TestErasureCodeShec
20
21 #include <errno.h>
22 #include <pthread.h>
23 #include <stdlib.h>
24
25 #include "crush/CrushWrapper.h"
26 #include "osd/osd_types.h"
27 #include "include/stringify.h"
28 #include "erasure-code/shec/ErasureCodeShec.h"
29 #include "erasure-code/ErasureCodePlugin.h"
30 #include "global/global_context.h"
31 #include "gtest/gtest.h"
32
33 void* thread1(void* pParam);
34 void* thread2(void* pParam);
35 void* thread3(void* pParam);
36 void* thread4(void* pParam);
37 void* thread5(void* pParam);
38
39 static int g_flag = 0;
40
41 TEST(ErasureCodeShec, init_1)
42 {
43   //all parameters are normal values
44   ErasureCodeShecTableCache tcache;
45   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
46                                   tcache,
47                                   ErasureCodeShec::MULTIPLE);
48   ErasureCodeProfile *profile = new ErasureCodeProfile();
49   (*profile)["plugin"] = "shec";
50   (*profile)["technique"] = "";
51   (*profile)["crush-failure-domain"] = "osd";
52   (*profile)["k"] = "4";
53   (*profile)["m"] = "3";
54   (*profile)["c"] = "2";
55
56   int r = shec->init(*profile, &cerr);
57
58   //check profile
59   EXPECT_EQ(4, shec->k);
60   EXPECT_EQ(3, shec->m);
61   EXPECT_EQ(2, shec->c);
62   EXPECT_EQ(8, shec->w);
63   EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
64   EXPECT_STREQ("default", shec->rule_root.c_str());
65   EXPECT_STREQ("osd", shec->rule_failure_domain.c_str());
66   EXPECT_TRUE(shec->matrix != NULL);
67   EXPECT_EQ(0, r);
68
69   delete shec;
70   delete profile;
71 }
72
73 TEST(ErasureCodeShec, init_2)
74 {
75   //all parameters are normal values
76   ErasureCodeShecTableCache tcache;
77   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
78                                   tcache,
79                                   ErasureCodeShec::MULTIPLE);
80   ErasureCodeProfile *profile = new ErasureCodeProfile();
81   (*profile)["plugin"] = "shec";
82   (*profile)["technique"] = "";
83   (*profile)["crush-root"] = "test";
84   (*profile)["crush-failure-domain"] = "host";
85   (*profile)["k"] = "4";
86   (*profile)["m"] = "3";
87   (*profile)["c"] = "2";
88   (*profile)["w"] = "8";
89
90   int r = shec->init(*profile, &cerr);
91
92   //check profile
93   EXPECT_EQ(4, shec->k);
94   EXPECT_EQ(3, shec->m);
95   EXPECT_EQ(2, shec->c);
96   EXPECT_EQ(8, shec->w);
97   EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
98   EXPECT_STREQ("test", shec->rule_root.c_str());
99   EXPECT_STREQ("host", shec->rule_failure_domain.c_str());
100   EXPECT_TRUE(shec->matrix != NULL);
101   EXPECT_EQ(0, r);
102
103   delete shec;
104   delete profile;
105 }
106
107 TEST(ErasureCodeShec, init_3)
108 {
109   //all parameters are normal values
110   ErasureCodeShecTableCache tcache;
111   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
112                                   tcache,
113                                   ErasureCodeShec::MULTIPLE);
114   ErasureCodeProfile *profile = new ErasureCodeProfile();
115   (*profile)["plugin"] = "shec";
116   (*profile)["technique"] = "";
117   (*profile)["crush-failure-domain"] = "osd";
118   (*profile)["k"] = "4";
119   (*profile)["m"] = "3";
120   (*profile)["c"] = "2";
121   (*profile)["w"] = "16";
122
123   int r = shec->init(*profile, &cerr);
124
125   //check profile
126   EXPECT_EQ(4, shec->k);
127   EXPECT_EQ(3, shec->m);
128   EXPECT_EQ(2, shec->c);
129   EXPECT_EQ(16, shec->w);
130   EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
131   EXPECT_STREQ("default", shec->rule_root.c_str());
132   EXPECT_STREQ("osd", shec->rule_failure_domain.c_str());
133   EXPECT_TRUE(shec->matrix != NULL);
134   EXPECT_EQ(0, r);
135
136   delete shec;
137   delete profile;
138 }
139
140 TEST(ErasureCodeShec, init_4)
141 {
142   //all parameters are normal values
143   ErasureCodeShecTableCache tcache;
144   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
145                                   tcache,
146                                   ErasureCodeShec::MULTIPLE);
147   ErasureCodeProfile *profile = new ErasureCodeProfile();
148   (*profile)["plugin"] = "shec";
149   (*profile)["technique"] = "";
150   (*profile)["crush-failure-domain"] = "osd";
151   (*profile)["k"] = "4";
152   (*profile)["m"] = "3";
153   (*profile)["c"] = "2";
154   (*profile)["w"] = "32";
155
156   int r = shec->init(*profile, &cerr);
157
158   //check profile
159   EXPECT_EQ(4, shec->k);
160   EXPECT_EQ(3, shec->m);
161   EXPECT_EQ(2, shec->c);
162   EXPECT_EQ(32, shec->w);
163   EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
164   EXPECT_STREQ("default", shec->rule_root.c_str());
165   EXPECT_STREQ("osd", shec->rule_failure_domain.c_str());
166   EXPECT_TRUE(shec->matrix != NULL);
167   EXPECT_EQ(0, r);
168
169   delete shec;
170   delete profile;
171 }
172
173 TEST(ErasureCodeShec, init_5)
174 {
175   ErasureCodeShecTableCache tcache;
176   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
177                                   tcache,
178                                   ErasureCodeShec::MULTIPLE);
179   ErasureCodeProfile *profile = new ErasureCodeProfile();
180   //plugin is not specified
181   (*profile)["technique"] = "";
182   (*profile)["crush-failure-domain"] = "osd";
183   (*profile)["k"] = "4";
184   (*profile)["m"] = "3";
185   (*profile)["c"] = "2";
186
187   int r = shec->init(*profile, &cerr);
188
189   EXPECT_TRUE(shec->matrix != NULL);
190   EXPECT_EQ(0, r);
191
192   delete shec;
193   delete profile;
194 }
195
196 TEST(ErasureCodeShec, init_6)
197 {
198   ErasureCodeShecTableCache tcache;
199   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
200                                   tcache,
201                                   ErasureCodeShec::MULTIPLE);
202   ErasureCodeProfile *profile = new ErasureCodeProfile();
203   (*profile)["plugin"] = "jerasure";    //unexpected value
204   (*profile)["technique"] = "";
205   (*profile)["crush-failure-domain"] = "osd";
206   (*profile)["k"] = "4";
207   (*profile)["m"] = "3";
208   (*profile)["c"] = "2";
209
210   int r = shec->init(*profile, &cerr);
211
212   EXPECT_TRUE(shec->matrix != NULL);
213   EXPECT_EQ(0, r);
214
215   delete shec;
216   delete profile;
217 }
218
219 TEST(ErasureCodeShec, init_7)
220 {
221   ErasureCodeShecTableCache tcache;
222   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
223                                   tcache,
224                                   ErasureCodeShec::MULTIPLE);
225   ErasureCodeProfile *profile = new ErasureCodeProfile();
226   (*profile)["plugin"] = "abc"; //unexpected value
227   (*profile)["technique"] = "";
228   (*profile)["crush-failure-domain"] = "osd";
229   (*profile)["k"] = "4";
230   (*profile)["m"] = "3";
231   (*profile)["c"] = "2";
232
233   int r = shec->init(*profile, &cerr);
234
235   EXPECT_TRUE(shec->matrix != NULL);
236   EXPECT_EQ(0, r);
237
238   delete shec;
239   delete profile;
240 }
241
242 TEST(ErasureCodeShec, init_8)
243 {
244   ErasureCodeShecTableCache tcache;
245   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
246                                   tcache,
247                                   ErasureCodeShec::MULTIPLE);
248   ErasureCodeProfile *profile = new ErasureCodeProfile();
249   (*profile)["plugin"] = "shec";
250   (*profile)["technique"] = "";
251   (*profile)["crush-failure-domain"] = "osd";
252   (*profile)["k"] = "4";
253   (*profile)["m"] = "3";
254   (*profile)["c"] = "2";
255
256   int r = shec->init(*profile, &cerr);
257
258   EXPECT_TRUE(shec->matrix != NULL);
259   EXPECT_EQ(0, r);
260
261   delete shec;
262   delete profile;
263 }
264
265 TEST(ErasureCodeShec, init_9)
266 {
267   ErasureCodeShecTableCache tcache;
268   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
269                                   tcache,
270                                   ErasureCodeShec::MULTIPLE);
271   ErasureCodeProfile *profile = new ErasureCodeProfile();
272   (*profile)["plugin"] = "shec";
273   (*profile)["technique"] = "";
274   (*profile)["crush-root"] = "abc";     //unexpected value
275   (*profile)["crush-failure-domain"] = "osd";
276   (*profile)["k"] = "4";
277   (*profile)["m"] = "3";
278   (*profile)["c"] = "2";
279
280   int r = shec->init(*profile, &cerr);
281
282   EXPECT_TRUE(shec->matrix != NULL);
283   EXPECT_EQ(0, r);
284
285   delete shec;
286   delete profile;
287 }
288
289 TEST(ErasureCodeShec, init_10)
290 {
291   ErasureCodeShecTableCache tcache;
292   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
293                                   tcache,
294                                   ErasureCodeShec::MULTIPLE);
295   ErasureCodeProfile *profile = new ErasureCodeProfile();
296   (*profile)["plugin"] = "shec";
297   (*profile)["technique"] = "";
298   (*profile)["crush-failure-domain"] = "abc";   //unexpected value
299   (*profile)["k"] = "4";
300   (*profile)["m"] = "3";
301   (*profile)["c"] = "2";
302
303   int r = shec->init(*profile, &cerr);
304
305   EXPECT_TRUE(shec->matrix != NULL);
306   EXPECT_EQ(0, r);
307
308   delete shec;
309   delete profile;
310 }
311
312 TEST(ErasureCodeShec, init_11)
313 {
314   ErasureCodeShecTableCache tcache;
315   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
316                                   tcache,
317                                   ErasureCodeShec::MULTIPLE);
318   ErasureCodeProfile *profile = new ErasureCodeProfile();
319   (*profile)["plugin"] = "shec";
320   (*profile)["technique"] = "abc";              //unexpected value
321   (*profile)["crush-failure-domain"] = "osd";
322   (*profile)["k"] = "4";
323   (*profile)["m"] = "3";
324   (*profile)["c"] = "2";
325
326   int r = shec->init(*profile, &cerr);
327
328   EXPECT_TRUE(shec->matrix != NULL);
329   EXPECT_EQ(0, r);
330
331   delete shec;
332   delete profile;
333 }
334
335 TEST(ErasureCodeShec, init_12)
336 {
337   ErasureCodeShecTableCache tcache;
338   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
339                                   tcache,
340                                   ErasureCodeShec::MULTIPLE);
341   ErasureCodeProfile *profile = new ErasureCodeProfile();
342   (*profile)["plugin"] = "shec";
343   (*profile)["technique"] = "";
344   (*profile)["crush-failure-domain"] = "osd";
345   (*profile)["k"] = "-1";       //unexpected value
346   (*profile)["m"] = "3";
347   (*profile)["c"] = "2";
348
349   int r = shec->init(*profile, &cerr);
350
351   EXPECT_EQ(-EINVAL, r);
352
353   delete shec;
354   delete profile;
355 }
356
357 TEST(ErasureCodeShec, init_13)
358 {
359   ErasureCodeShecTableCache tcache;
360   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
361                                   tcache,
362                                   ErasureCodeShec::MULTIPLE);
363   ErasureCodeProfile *profile = new ErasureCodeProfile();
364   (*profile)["plugin"] = "shec";
365   (*profile)["technique"] = "";
366   (*profile)["crush-failure-domain"] = "abc";
367   (*profile)["k"] = "0.1";      //unexpected value
368   (*profile)["m"] = "3";
369   (*profile)["c"] = "2";
370
371   int r = shec->init(*profile, &cerr);
372
373   EXPECT_EQ(-EINVAL, r);
374
375   delete shec;
376   delete profile;
377 }
378
379 TEST(ErasureCodeShec, init_14)
380 {
381   ErasureCodeShecTableCache tcache;
382   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
383                                   tcache,
384                                   ErasureCodeShec::MULTIPLE);
385   ErasureCodeProfile *profile = new ErasureCodeProfile();
386   (*profile)["plugin"] = "shec";
387   (*profile)["technique"] = "";
388   (*profile)["crush-failure-domain"] = "osd";
389   (*profile)["k"] = "a";                //unexpected value
390   (*profile)["m"] = "3";
391   (*profile)["c"] = "2";
392
393   int r = shec->init(*profile, &cerr);
394
395   EXPECT_EQ(-EINVAL, r);
396
397   delete shec;
398   delete profile;
399 }
400
401 TEST(ErasureCodeShec, init_15)
402 {
403   ErasureCodeShecTableCache tcache;
404   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
405                                   tcache,
406                                   ErasureCodeShec::MULTIPLE);
407   ErasureCodeProfile *profile = new ErasureCodeProfile();
408   (*profile)["plugin"] = "shec";
409   (*profile)["technique"] = "";
410   (*profile)["crush-failure-domain"] = "osd";
411   //k is not specified
412   (*profile)["m"] = "3";
413   (*profile)["c"] = "2";
414
415   int r = shec->init(*profile, &cerr);
416
417   EXPECT_EQ(-EINVAL, r);
418
419   delete shec;
420   delete profile;
421 }
422
423 TEST(ErasureCodeShec, init_16)
424 {
425   ErasureCodeShecTableCache tcache;
426   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
427                                   tcache,
428                                   ErasureCodeShec::MULTIPLE);
429   ErasureCodeProfile *profile = new ErasureCodeProfile();
430   (*profile)["plugin"] = "shec";
431   (*profile)["technique"] = "";
432   (*profile)["crush-failure-domain"] = "osd";
433   (*profile)["k"] = "4";
434   (*profile)["m"] = "-1";               //unexpected value
435   (*profile)["c"] = "2";
436
437   int r = shec->init(*profile, &cerr);
438
439   EXPECT_EQ(-EINVAL, r);
440
441   delete shec;
442   delete profile;
443 }
444
445 TEST(ErasureCodeShec, init_17)
446 {
447   ErasureCodeShecTableCache tcache;
448   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
449                                   tcache,
450                                   ErasureCodeShec::MULTIPLE);
451   ErasureCodeProfile *profile = new ErasureCodeProfile();
452   (*profile)["plugin"] = "shec";
453   (*profile)["technique"] = "";
454   (*profile)["crush-failure-domain"] = "osd";
455   (*profile)["k"] = "4";
456   (*profile)["m"] = "0.1";              //unexpected value
457   (*profile)["c"] = "2";
458
459   int r = shec->init(*profile, &cerr);
460
461   EXPECT_EQ(-EINVAL, r);
462
463   delete shec;
464   delete profile;
465 }
466
467 TEST(ErasureCodeShec, init_18)
468 {
469   ErasureCodeShecTableCache tcache;
470   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
471                                   tcache,
472                                   ErasureCodeShec::MULTIPLE);
473   ErasureCodeProfile *profile = new ErasureCodeProfile();
474   (*profile)["plugin"] = "shec";
475   (*profile)["technique"] = "";
476   (*profile)["crush-failure-domain"] = "osd";
477   (*profile)["k"] = "4";
478   (*profile)["m"] = "a";                //unexpected value
479   (*profile)["c"] = "2";
480
481   int r = shec->init(*profile, &cerr);
482
483   EXPECT_EQ(-EINVAL, r);
484
485   delete shec;
486   delete profile;
487 }
488
489 TEST(ErasureCodeShec, init_19)
490 {
491   ErasureCodeShecTableCache tcache;
492   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
493                                   tcache,
494                                   ErasureCodeShec::MULTIPLE);
495   ErasureCodeProfile *profile = new ErasureCodeProfile();
496   (*profile)["plugin"] = "shec";
497   (*profile)["technique"] = "";
498   (*profile)["crush-failure-domain"] = "osd";
499   (*profile)["k"] = "4";
500   //m is not specified
501   (*profile)["c"] = "2";
502
503   int r = shec->init(*profile, &cerr);
504
505   EXPECT_EQ(-EINVAL, r);
506
507   delete shec;
508   delete profile;
509 }
510
511 TEST(ErasureCodeShec, init_20)
512 {
513   ErasureCodeShecTableCache tcache;
514   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
515                                   tcache,
516                                   ErasureCodeShec::MULTIPLE);
517   ErasureCodeProfile *profile = new ErasureCodeProfile();
518   (*profile)["plugin"] = "shec";
519   (*profile)["technique"] = "";
520   (*profile)["crush-failure-domain"] = "osd";
521   (*profile)["k"] = "4";
522   (*profile)["m"] = "3";
523   (*profile)["c"] = "-1";               //unexpected value
524
525   int r = shec->init(*profile, &cerr);
526
527   EXPECT_EQ(-EINVAL, r);
528
529   delete shec;
530   delete profile;
531 }
532
533 TEST(ErasureCodeShec, init_21)
534 {
535   ErasureCodeShecTableCache tcache;
536   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
537                                   tcache,
538                                   ErasureCodeShec::MULTIPLE);
539   ErasureCodeProfile *profile = new ErasureCodeProfile();
540   (*profile)["plugin"] = "shec";
541   (*profile)["technique"] = "";
542   (*profile)["crush-failure-domain"] = "osd";
543   (*profile)["k"] = "4";
544   (*profile)["m"] = "3";
545   (*profile)["c"] = "0.1";              //unexpected value
546
547   int r = shec->init(*profile, &cerr);
548
549   EXPECT_EQ(-EINVAL, r);
550
551   delete shec;
552   delete profile;
553 }
554
555 TEST(ErasureCodeShec, init_22)
556 {
557   ErasureCodeShecTableCache tcache;
558   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
559                                   tcache,
560                                   ErasureCodeShec::MULTIPLE);
561   ErasureCodeProfile *profile = new ErasureCodeProfile();
562   (*profile)["plugin"] = "shec";
563   (*profile)["technique"] = "";
564   (*profile)["crush-failure-domain"] = "osd";
565   (*profile)["k"] = "4";
566   (*profile)["m"] = "3";
567   (*profile)["c"] = "a";                //unexpected value
568
569   int r = shec->init(*profile, &cerr);
570
571   EXPECT_EQ(-EINVAL, r);
572
573   delete shec;
574   delete profile;
575 }
576
577 TEST(ErasureCodeShec, init_23)
578 {
579   ErasureCodeShecTableCache tcache;
580   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
581                                   tcache,
582                                   ErasureCodeShec::MULTIPLE);
583   ErasureCodeProfile *profile = new ErasureCodeProfile();
584   (*profile)["plugin"] = "shec";
585   (*profile)["technique"] = "";
586   (*profile)["crush-failure-domain"] = "osd";
587   (*profile)["k"] = "4";
588   (*profile)["m"] = "3";
589   //c is not specified
590
591   int r = shec->init(*profile, &cerr);
592
593   EXPECT_EQ(-EINVAL, r);
594
595   delete shec;
596   delete profile;
597 }
598
599 TEST(ErasureCodeShec, init_24)
600 {
601   ErasureCodeShecTableCache tcache;
602   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
603                                   tcache,
604                                   ErasureCodeShec::MULTIPLE);
605   ErasureCodeProfile *profile = new ErasureCodeProfile();
606   (*profile)["plugin"] = "shec";
607   (*profile)["technique"] = "";
608   (*profile)["crush-failure-domain"] = "osd";
609   (*profile)["k"] = "4";
610   (*profile)["m"] = "3";
611   (*profile)["c"] = "2";
612   (*profile)["w"] = "1";                //unexpected value
613
614   int r = shec->init(*profile, &cerr);
615
616   EXPECT_TRUE(shec->matrix != NULL);
617   EXPECT_EQ(0, r);
618   EXPECT_EQ(4, shec->k);
619   EXPECT_EQ(3, shec->m);
620   EXPECT_EQ(2, shec->c);
621   EXPECT_EQ(8, shec->w);
622   //w is default value
623
624   delete shec;
625   delete profile;
626 }
627
628 TEST(ErasureCodeShec, init_25)
629 {
630   ErasureCodeShecTableCache tcache;
631   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
632                                   tcache,
633                                   ErasureCodeShec::MULTIPLE);
634   ErasureCodeProfile *profile = new ErasureCodeProfile();
635   (*profile)["plugin"] = "shec";
636   (*profile)["technique"] = "";
637   (*profile)["crush-failure-domain"] = "osd";
638   (*profile)["k"] = "4";
639   (*profile)["m"] = "3";
640   (*profile)["c"] = "2";
641   (*profile)["w"] = "-1";               //unexpected value
642
643   int r = shec->init(*profile, &cerr);
644
645   EXPECT_TRUE(shec->matrix != NULL);
646   EXPECT_EQ(0, r);
647   EXPECT_EQ(4, shec->k);
648   EXPECT_EQ(3, shec->m);
649   EXPECT_EQ(2, shec->c);
650   EXPECT_EQ(8, shec->w);
651   //w is default value
652
653   delete shec;
654   delete profile;
655 }
656
657 TEST(ErasureCodeShec, init_26)
658 {
659   ErasureCodeShecTableCache tcache;
660   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
661                                   tcache,
662                                   ErasureCodeShec::MULTIPLE);
663   ErasureCodeProfile *profile = new ErasureCodeProfile();
664   (*profile)["plugin"] = "shec";
665   (*profile)["technique"] = "";
666   (*profile)["crush-failure-domain"] = "osd";
667   (*profile)["k"] = "4";
668   (*profile)["m"] = "3";
669   (*profile)["c"] = "2";
670   (*profile)["w"] = "0.1";              //unexpected value
671
672   int r = shec->init(*profile, &cerr);
673
674   EXPECT_TRUE(shec->matrix != NULL);
675   EXPECT_EQ(0, r);
676   EXPECT_EQ(4, shec->k);
677   EXPECT_EQ(3, shec->m);
678   EXPECT_EQ(2, shec->c);
679   EXPECT_EQ(8, shec->w);
680   //w is default value
681
682   delete shec;
683   delete profile;
684 }
685
686 TEST(ErasureCodeShec, init_27)
687 {
688   ErasureCodeShecTableCache tcache;
689   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
690                                   tcache,
691                                   ErasureCodeShec::MULTIPLE);
692   ErasureCodeProfile *profile = new ErasureCodeProfile();
693   (*profile)["plugin"] = "shec";
694   (*profile)["technique"] = "";
695   (*profile)["crush-failure-domain"] = "osd";
696   (*profile)["k"] = "4";
697   (*profile)["m"] = "3";
698   (*profile)["c"] = "2";
699   (*profile)["w"] = "a";                //unexpected value
700
701   int r = shec->init(*profile, &cerr);
702
703   EXPECT_TRUE(shec->matrix != NULL);
704   EXPECT_EQ(0, r);
705   EXPECT_EQ(4, shec->k);
706   EXPECT_EQ(3, shec->m);
707   EXPECT_EQ(2, shec->c);
708   EXPECT_EQ(8, shec->w);
709   //w is default value
710
711   delete shec;
712   delete profile;
713 }
714
715 TEST(ErasureCodeShec, init_28)
716 {
717   ErasureCodeShecTableCache tcache;
718   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
719                                   tcache,
720                                   ErasureCodeShec::MULTIPLE);
721   ErasureCodeProfile *profile = new ErasureCodeProfile();
722   (*profile)["plugin"] = "shec";
723   (*profile)["technique"] = "";
724   (*profile)["crush-failure-domain"] = "osd";
725   (*profile)["k"] = "4";
726   (*profile)["m"] = "3";
727   (*profile)["c"] = "10";       //c > m
728
729   int r = shec->init(*profile, &cerr);
730
731   EXPECT_EQ(-EINVAL, r);
732
733   delete shec;
734   delete profile;
735 }
736
737 TEST(ErasureCodeShec, init_29)
738 {
739   ErasureCodeShecTableCache tcache;
740   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
741                                   tcache,
742                                   ErasureCodeShec::MULTIPLE);
743   ErasureCodeProfile *profile = new ErasureCodeProfile();
744   (*profile)["plugin"] = "shec";
745   (*profile)["technique"] = "";
746   (*profile)["crush-failure-domain"] = "osd";
747   //k is not specified
748   //m is not specified
749   //c is not specified
750
751   int r = shec->init(*profile, &cerr);
752
753   EXPECT_TRUE(shec->matrix != NULL);
754   EXPECT_EQ(0, r);
755   //k,m,c are default values
756   EXPECT_EQ(4, shec->k);
757   EXPECT_EQ(3, shec->m);
758   EXPECT_EQ(2, shec->c);
759
760   delete shec;
761   delete profile;
762 }
763
764 TEST(ErasureCodeShec, init_30)
765 {
766   ErasureCodeShecTableCache tcache;
767   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
768                                   tcache,
769                                   ErasureCodeShec::MULTIPLE);
770   ErasureCodeProfile *profile = new ErasureCodeProfile();
771   (*profile)["plugin"] = "shec";
772   (*profile)["technique"] = "";
773   (*profile)["crush-failure-domain"] = "osd";
774   (*profile)["k"] = "12";
775   (*profile)["m"] = "8";
776   (*profile)["c"] = "8";
777
778   int r = shec->init(*profile, &cerr);
779
780   EXPECT_TRUE(shec->matrix != NULL);
781   EXPECT_EQ(0, r);
782   EXPECT_EQ(12, shec->k);
783   EXPECT_EQ(8, shec->m);
784   EXPECT_EQ(8, shec->c);
785
786   delete shec;
787   delete profile;
788 }
789
790 TEST(ErasureCodeShec, init_31)
791 {
792   ErasureCodeShecTableCache tcache;
793   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
794                                   tcache,
795                                   ErasureCodeShec::MULTIPLE);
796   ErasureCodeProfile *profile = new ErasureCodeProfile();
797   (*profile)["plugin"] = "shec";
798   (*profile)["technique"] = "";
799   (*profile)["crush-failure-domain"] = "osd";
800   (*profile)["k"] = "13";
801   (*profile)["m"] = "7";
802   (*profile)["c"] = "7";
803
804   int r = shec->init(*profile, &cerr);
805
806   EXPECT_EQ(-EINVAL, r);
807
808   delete shec;
809   delete profile;
810 }
811
812 TEST(ErasureCodeShec, init_32)
813 {
814   ErasureCodeShecTableCache tcache;
815   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
816                                   tcache,
817                                   ErasureCodeShec::MULTIPLE);
818   ErasureCodeProfile *profile = new ErasureCodeProfile();
819   (*profile)["plugin"] = "shec";
820   (*profile)["technique"] = "";
821   (*profile)["crush-failure-domain"] = "osd";
822   (*profile)["k"] = "7";
823   (*profile)["m"] = "13";
824   (*profile)["c"] = "13";
825
826   int r = shec->init(*profile, &cerr);
827
828   EXPECT_EQ(-EINVAL, r);
829
830   delete shec;
831   delete profile;
832 }
833
834 TEST(ErasureCodeShec, init_33)
835 {
836   ErasureCodeShecTableCache tcache;
837   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
838                                   tcache,
839                                   ErasureCodeShec::MULTIPLE);
840   ErasureCodeProfile *profile = new ErasureCodeProfile();
841   (*profile)["plugin"] = "shec";
842   (*profile)["technique"] = "";
843   (*profile)["crush-failure-domain"] = "osd";
844   (*profile)["k"] = "12";
845   (*profile)["m"] = "9";
846   (*profile)["c"] = "8";
847
848   int r = shec->init(*profile, &cerr);
849
850   EXPECT_EQ(-EINVAL, r);
851
852   delete shec;
853   delete profile;
854 }
855
856 TEST(ErasureCodeShec, init_34)
857 {
858   ErasureCodeShecTableCache tcache;
859   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
860                                   tcache,
861                                   ErasureCodeShec::MULTIPLE);
862   ErasureCodeProfile *profile = new ErasureCodeProfile();
863   (*profile)["plugin"] = "shec";
864   (*profile)["technique"] = "";
865   (*profile)["crush-failure-domain"] = "osd";
866   (*profile)["k"] = "8";
867   (*profile)["m"] = "12";
868   (*profile)["c"] = "12";
869
870   int r = shec->init(*profile, &cerr);
871
872   EXPECT_EQ(-EINVAL, r);
873
874   delete shec;
875   delete profile;
876 }
877
878 TEST(ErasureCodeShec, init2_4)
879 {
880   //all parameters are normal values
881   ErasureCodeShecTableCache tcache;
882   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
883                                   tcache,
884                                   ErasureCodeShec::MULTIPLE);
885   ErasureCodeProfile *profile = new ErasureCodeProfile();
886   (*profile)["plugin"] = "shec";
887   (*profile)["technique"] = "";
888   (*profile)["crush-failure-domain"] = "osd";
889   (*profile)["k"] = "4";
890   (*profile)["m"] = "3";
891   (*profile)["c"] = "2";
892   shec->init(*profile, &cerr);
893   int r = shec->init(*profile, &cerr);  //init executed twice
894
895   //check profile
896   EXPECT_EQ(4, shec->k);
897   EXPECT_EQ(3, shec->m);
898   EXPECT_EQ(2, shec->c);
899   EXPECT_EQ(8, shec->w);
900   EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
901   EXPECT_STREQ("default", shec->rule_root.c_str());
902   EXPECT_STREQ("osd", shec->rule_failure_domain.c_str());
903   EXPECT_TRUE(shec->matrix != NULL);
904   EXPECT_EQ(0, r);
905
906   delete shec;
907   delete profile;
908 }
909
910 TEST(ErasureCodeShec, init2_5)
911 {
912   //all parameters are normal values
913   ErasureCodeShecTableCache tcache;
914   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
915                                   tcache,
916                                   ErasureCodeShec::MULTIPLE);
917   ErasureCodeProfile *profile = new ErasureCodeProfile();
918   ErasureCodeProfile *profile2 = new ErasureCodeProfile();
919   (*profile)["plugin"] = "shec";
920   (*profile)["technique"] = "";
921   (*profile)["crush-failure-domain"] = "host";
922   (*profile)["k"] = "10";
923   (*profile)["m"] = "6";
924   (*profile)["c"] = "5";
925   (*profile)["w"] = "16";
926
927   int r = shec->init(*profile, &cerr);
928
929   //reexecute init
930   (*profile2)["plugin"] = "shec";
931   (*profile2)["technique"] = "";
932   (*profile2)["crush-failure-domain"] = "osd";
933   (*profile2)["k"] = "4";
934   (*profile2)["m"] = "3";
935   (*profile2)["c"] = "2";
936   shec->init(*profile2, &cerr);
937
938   EXPECT_EQ(4, shec->k);
939   EXPECT_EQ(3, shec->m);
940   EXPECT_EQ(2, shec->c);
941   EXPECT_EQ(8, shec->w);
942   EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
943   EXPECT_STREQ("default", shec->rule_root.c_str());
944   EXPECT_STREQ("osd", shec->rule_failure_domain.c_str());
945   EXPECT_TRUE(shec->matrix != NULL);
946   EXPECT_EQ(0, r);
947
948   delete shec;
949   delete profile;
950 }
951
952 TEST(ErasureCodeShec, minimum_to_decode_8)
953 {
954   //init
955   ErasureCodeShecTableCache tcache;
956   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
957                                   tcache,
958                                   ErasureCodeShec::MULTIPLE);
959   ErasureCodeProfile *profile = new ErasureCodeProfile();
960   (*profile)["plugin"] = "shec";
961   (*profile)["technique"] = "";
962   (*profile)["crush-failure-domain"] = "osd";
963   (*profile)["k"] = "4";
964   (*profile)["m"] = "3";
965   (*profile)["c"] = "2";
966   shec->init(*profile, &cerr);
967
968   //minimum_to_decode
969   set<int> want_to_decode;
970   set<int> available_chunks;
971   set<int> minimum_chunks;
972
973   for (int i = 0; i < 8; ++i) {
974     want_to_decode.insert(i);
975   }
976   for (int i = 0; i < 5; ++i) {
977     available_chunks.insert(i);
978   }
979
980   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
981                                   &minimum_chunks);
982   EXPECT_EQ(-EINVAL, r);
983
984   delete shec;
985   delete profile;
986 }
987
988 TEST(ErasureCodeShec, minimum_to_decode_9)
989 {
990   //init
991   ErasureCodeShecTableCache tcache;
992   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
993                                   tcache,
994                                   ErasureCodeShec::MULTIPLE);
995   ErasureCodeProfile *profile = new ErasureCodeProfile();
996   (*profile)["plugin"] = "shec";
997   (*profile)["technique"] = "";
998   (*profile)["crush-failure-domain"] = "osd";
999   (*profile)["k"] = "4";
1000   (*profile)["m"] = "3";
1001   (*profile)["c"] = "2";
1002   shec->init(*profile, &cerr);
1003
1004   //minimum_to_decode
1005   set<int> want_to_decode;
1006   set<int> available_chunks;
1007   set<int> minimum_chunks;
1008
1009   for (int i = 0; i < 4; ++i) {
1010     want_to_decode.insert(i);
1011   }
1012   for (int i = 0; i < 8; ++i) {
1013     available_chunks.insert(i);
1014   }
1015
1016   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
1017                                   &minimum_chunks);
1018   EXPECT_EQ(-EINVAL, r);
1019
1020   delete shec;
1021   delete profile;
1022 }
1023
1024 TEST(ErasureCodeShec, minimum_to_decode_10)
1025 {
1026   //init
1027   ErasureCodeShecTableCache tcache;
1028   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1029                                   tcache,
1030                                   ErasureCodeShec::MULTIPLE);
1031   ErasureCodeProfile *profile = new ErasureCodeProfile();
1032   (*profile)["plugin"] = "shec";
1033   (*profile)["technique"] = "";
1034   (*profile)["crush-failure-domain"] = "osd";
1035   (*profile)["k"] = "4";
1036   (*profile)["m"] = "3";
1037   (*profile)["c"] = "2";
1038   shec->init(*profile, &cerr);
1039
1040   //minimum_to_decode
1041   set<int> want_to_decode;
1042   set<int> available_chunks;
1043   set<int> minimum_chunks;
1044
1045   for (int i = 0; i < 7; ++i) {
1046     want_to_decode.insert(i);
1047   }
1048   for (int i = 4; i < 7; ++i) {
1049     available_chunks.insert(i);
1050   }
1051
1052   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
1053                                   &minimum_chunks);
1054   EXPECT_EQ(-EIO, r);
1055
1056   delete shec;
1057   delete profile;
1058 }
1059
1060 TEST(ErasureCodeShec, minimum_to_decode_11)
1061 {
1062   //init
1063   ErasureCodeShecTableCache tcache;
1064   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1065                                   tcache,
1066                                   ErasureCodeShec::MULTIPLE);
1067   ErasureCodeProfile *profile = new ErasureCodeProfile();
1068   (*profile)["plugin"] = "shec";
1069   (*profile)["technique"] = "";
1070   (*profile)["crush-failure-domain"] = "osd";
1071   (*profile)["k"] = "4";
1072   (*profile)["m"] = "3";
1073   (*profile)["c"] = "2";
1074   shec->init(*profile, &cerr);
1075
1076   //minimum_to_decode
1077   set<int> want_to_decode;
1078   set<int> available_chunks;
1079   set<int> minimum_chunks;
1080
1081   for (int i = 0; i < 5; ++i) {
1082     want_to_decode.insert(i);
1083   }
1084   for (int i = 4; i < 7; ++i) {
1085     available_chunks.insert(i);
1086   }
1087
1088   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
1089                                   &minimum_chunks);
1090   EXPECT_EQ(-EIO, r);
1091
1092   delete shec;
1093   delete profile;
1094 }
1095
1096 TEST(ErasureCodeShec, minimum_to_decode_12)
1097 {
1098   //init
1099   ErasureCodeShecTableCache tcache;
1100   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1101                                   tcache,
1102                                   ErasureCodeShec::MULTIPLE);
1103   ErasureCodeProfile *profile = new ErasureCodeProfile();
1104   (*profile)["plugin"] = "shec";
1105   (*profile)["technique"] = "";
1106   (*profile)["crush-failure-domain"] = "osd";
1107   (*profile)["k"] = "4";
1108   (*profile)["m"] = "3";
1109   (*profile)["c"] = "2";
1110   shec->init(*profile, &cerr);
1111
1112   //minimum_to_decode
1113   set<int> want_to_decode;
1114   set<int> available_chunks;
1115   //minimum_chunks is NULL
1116
1117   for (int i = 0; i < 7; ++i) {
1118     want_to_decode.insert(i);
1119     available_chunks.insert(i);
1120   }
1121
1122   int r = shec->minimum_to_decode(want_to_decode, available_chunks, NULL);
1123   EXPECT_EQ(-EINVAL, r);
1124
1125   delete shec;
1126   delete profile;
1127 }
1128
1129 TEST(ErasureCodeShec, minimum_to_decode_13)
1130 {
1131   //init
1132   ErasureCodeShecTableCache tcache;
1133   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1134                                   tcache,
1135                                   ErasureCodeShec::MULTIPLE);
1136   ErasureCodeProfile *profile = new ErasureCodeProfile();
1137   (*profile)["plugin"] = "shec";
1138   (*profile)["technique"] = "";
1139   (*profile)["crush-failure-domain"] = "osd";
1140   (*profile)["k"] = "4";
1141   (*profile)["m"] = "3";
1142   (*profile)["c"] = "2";
1143   shec->init(*profile, &cerr);
1144
1145   //minimum_to_decode
1146   set<int> want_to_decode;
1147   set<int> available_chunks;
1148   set<int> minimum_chunks, minimum;
1149
1150   for (int i = 0; i < 7; ++i) {
1151     want_to_decode.insert(i);
1152     available_chunks.insert(i);
1153   }
1154   shec->minimum_to_decode(want_to_decode, available_chunks, &minimum_chunks);
1155   minimum = minimum_chunks;             //normal value
1156   for (int i = 100; i < 120; ++i) {
1157     minimum_chunks.insert(i);   //insert extra data
1158   }
1159
1160   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
1161                                   &minimum_chunks);
1162   EXPECT_TRUE(shec->matrix != NULL);
1163   EXPECT_EQ(0, r);
1164   EXPECT_EQ(minimum, minimum_chunks);
1165
1166   delete shec;
1167   delete profile;
1168 }
1169
1170 TEST(ErasureCodeShec, minimum_to_decode2_1)
1171 {
1172   //init
1173   ErasureCodeShecTableCache tcache;
1174   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1175                                   tcache,
1176                                   ErasureCodeShec::MULTIPLE);
1177   ErasureCodeProfile *profile = new ErasureCodeProfile();
1178   (*profile)["plugin"] = "shec";
1179   (*profile)["technique"] = "";
1180   (*profile)["crush-failure-domain"] = "osd";
1181   (*profile)["k"] = "4";
1182   (*profile)["m"] = "3";
1183   (*profile)["c"] = "2";
1184   shec->init(*profile, &cerr);
1185
1186   //minimum_to_decode
1187   set<int> want_to_decode;
1188   set<int> available_chunks;
1189   set<int> minimum_chunks;
1190
1191   want_to_decode.insert(0);
1192   available_chunks.insert(0);
1193   available_chunks.insert(1);
1194   available_chunks.insert(2);
1195
1196   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
1197                                   &minimum_chunks);
1198   EXPECT_TRUE(shec->matrix != NULL);
1199   EXPECT_EQ(0, r);
1200   EXPECT_TRUE(minimum_chunks.size());
1201
1202   delete shec;
1203   delete profile;
1204 }
1205
1206 TEST(ErasureCodeShec, minimum_to_decode2_3)
1207 {
1208   //init
1209   ErasureCodeShecTableCache tcache;
1210   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1211                                   tcache,
1212                                   ErasureCodeShec::MULTIPLE);
1213   ErasureCodeProfile *profile = new ErasureCodeProfile();
1214   (*profile)["plugin"] = "shec";
1215   (*profile)["technique"] = "";
1216   (*profile)["crush-failure-domain"] = "osd";
1217   (*profile)["k"] = "4";
1218   (*profile)["m"] = "3";
1219   (*profile)["c"] = "2";
1220   shec->init(*profile, &cerr);
1221
1222   //minimum_to_decode
1223   set<int> want_to_decode;
1224   set<int> available_chunks;
1225   set<int> minimum_chunks;
1226
1227   want_to_decode.insert(0);
1228   want_to_decode.insert(2);
1229   available_chunks.insert(0);
1230   available_chunks.insert(1);
1231   available_chunks.insert(2);
1232   available_chunks.insert(3);
1233
1234   pthread_t tid;
1235   g_flag = 0;
1236   pthread_create(&tid, NULL, thread1, shec);
1237   while (g_flag == 0) {
1238     usleep(1);
1239   }
1240   sleep(1);
1241   printf("*** test start ***\n");
1242   int r = shec->minimum_to_decode(want_to_decode, available_chunks,
1243                                   &minimum_chunks);
1244   EXPECT_TRUE(shec->matrix != NULL);
1245   EXPECT_EQ(0, r);
1246   EXPECT_EQ(want_to_decode, minimum_chunks);
1247   printf("*** test end ***\n");
1248   g_flag = 0;
1249   pthread_join(tid, NULL);
1250
1251   delete shec;
1252   delete profile;
1253 }
1254
1255 TEST(ErasureCodeShec, minimum_to_decode_with_cost_1)
1256 {
1257   //init
1258   ErasureCodeShecTableCache tcache;
1259   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1260                                   tcache,
1261                                   ErasureCodeShec::MULTIPLE);
1262   ErasureCodeProfile *profile = new ErasureCodeProfile();
1263   (*profile)["plugin"] = "shec";
1264   (*profile)["technique"] = "";
1265   (*profile)["crush-failure-domain"] = "osd";
1266   (*profile)["k"] = "4";
1267   (*profile)["m"] = "3";
1268   (*profile)["c"] = "2";
1269   shec->init(*profile, &cerr);
1270
1271   //minimum_to_decode_with_cost
1272   set<int> want_to_decode;
1273   map<int, int> available_chunks;
1274   set<int> minimum_chunks;
1275
1276   for (int i = 0; i < 7; ++i) {
1277     want_to_decode.insert(i);
1278     available_chunks.insert(make_pair(i, i));
1279   }
1280
1281   int r = shec->minimum_to_decode_with_cost(want_to_decode, available_chunks,
1282                                             &minimum_chunks);
1283   EXPECT_TRUE(shec->matrix != NULL);
1284   EXPECT_EQ(0, r);
1285   EXPECT_TRUE(minimum_chunks.size());
1286
1287   delete shec;
1288   delete profile;
1289 }
1290
1291 TEST(ErasureCodeShec, minimum_to_decode_with_cost_2_3)
1292 {
1293   //init
1294   ErasureCodeShecTableCache tcache;
1295   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1296                                   tcache,
1297                                   ErasureCodeShec::MULTIPLE);
1298   ErasureCodeProfile *profile = new ErasureCodeProfile();
1299   (*profile)["plugin"] = "shec";
1300   (*profile)["technique"] = "";
1301   (*profile)["crush-failure-domain"] = "osd";
1302   (*profile)["k"] = "4";
1303   (*profile)["m"] = "3";
1304   (*profile)["c"] = "2";
1305   shec->init(*profile, &cerr);
1306
1307   //minimum_to_decode_with_cost
1308   set<int> want_to_decode;
1309   map<int, int> available_chunks;
1310   set<int> minimum_chunks;
1311
1312   want_to_decode.insert(0);
1313   want_to_decode.insert(2);
1314   available_chunks[0] = 0;
1315   available_chunks[1] = 1;
1316   available_chunks[2] = 2;
1317   available_chunks[3] = 3;
1318
1319   pthread_t tid;
1320   g_flag = 0;
1321   pthread_create(&tid, NULL, thread2, shec);
1322   while (g_flag == 0) {
1323     usleep(1);
1324   }
1325   sleep(1);
1326   printf("*** test start ***\n");
1327   int r = shec->minimum_to_decode_with_cost(want_to_decode, available_chunks,
1328                                             &minimum_chunks);
1329   EXPECT_TRUE(shec->matrix != NULL);
1330   EXPECT_EQ(0, r);
1331   EXPECT_EQ(want_to_decode, minimum_chunks);
1332   printf("*** test end ***\n");
1333   g_flag = 0;
1334   pthread_join(tid, NULL);
1335
1336   delete shec;
1337   delete profile;
1338 }
1339
1340 TEST(ErasureCodeShec, encode_1)
1341 {
1342   //init
1343   ErasureCodeShecTableCache tcache;
1344   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1345                                   tcache,
1346                                   ErasureCodeShec::MULTIPLE);
1347   ErasureCodeProfile *profile = new ErasureCodeProfile();
1348   (*profile)["plugin"] = "shec";
1349   (*profile)["technique"] = "";
1350   (*profile)["crush-failure-domain"] = "osd";
1351   (*profile)["k"] = "4";
1352   (*profile)["m"] = "3";
1353   (*profile)["c"] = "2";
1354   shec->init(*profile, &cerr);
1355
1356   //encode
1357   bufferlist in;
1358   set<int> want_to_encode;
1359   map<int, bufferlist> encoded;
1360
1361   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1362             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1363             "0123"//128
1364   );
1365   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1366     want_to_encode.insert(i);
1367   }
1368
1369   int r = shec->encode(want_to_encode, in, &encoded);
1370   EXPECT_EQ(0, r);
1371   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1372   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1373
1374   //decode
1375   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1376   map<int, bufferlist> decoded;
1377   decoded.clear();
1378   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2),
1379                    encoded,
1380                    &decoded);
1381   EXPECT_TRUE(shec->matrix != NULL);
1382   EXPECT_EQ(0, r);
1383   EXPECT_EQ(2u, decoded.size());
1384   EXPECT_EQ(32u, decoded[0].length());
1385
1386   bufferlist out1, out2, usable;
1387   //out1 is "encoded"
1388   for (unsigned int i = 0; i < encoded.size(); ++i) {
1389     out1.append(encoded[i]);
1390   }
1391   //out2 is "decoded"
1392   r = shec->decode_concat(encoded, &out2);
1393   usable.substr_of(out2, 0, in.length());
1394   EXPECT_FALSE(out1 == in);
1395   EXPECT_TRUE(usable == in);
1396
1397   delete shec;
1398   delete profile;
1399 }
1400
1401 TEST(ErasureCodeShec, encode_2)
1402 {
1403   //init
1404   ErasureCodeShecTableCache tcache;
1405   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1406                                   tcache,
1407                                   ErasureCodeShec::MULTIPLE);
1408   ErasureCodeProfile *profile = new ErasureCodeProfile();
1409   (*profile)["plugin"] = "shec";
1410   (*profile)["technique"] = "";
1411   (*profile)["crush-failure-domain"] = "osd";
1412   (*profile)["k"] = "4";
1413   (*profile)["m"] = "3";
1414   (*profile)["c"] = "2";
1415   shec->init(*profile, &cerr);
1416
1417   //encode
1418   bufferlist in;
1419   set<int> want_to_encode;
1420   map<int, bufferlist> encoded;
1421
1422   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1423             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1424   );
1425   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1426     want_to_encode.insert(i);
1427   }
1428
1429   int r = shec->encode(want_to_encode, in, &encoded);
1430   EXPECT_EQ(0, r);
1431   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1432   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1433
1434   //decode
1435   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1436   map<int, bufferlist> decoded;
1437   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
1438                    &decoded);
1439   EXPECT_TRUE(shec->matrix != NULL);
1440   EXPECT_EQ(0, r);
1441   EXPECT_EQ(2u, decoded.size());
1442   EXPECT_EQ(32u, decoded[0].length());
1443
1444   bufferlist out1, out2, usable;
1445   //out1 is "encoded"
1446   for (unsigned int i = 0; i < encoded.size(); ++i)
1447     out1.append(encoded[i]);
1448   //out2 is "decoded"
1449   shec->decode_concat(encoded, &out2);
1450   usable.substr_of(out2, 0, in.length());
1451   EXPECT_FALSE(out1 == in);
1452   EXPECT_TRUE(usable == in);
1453
1454   delete shec;
1455   delete profile;
1456 }
1457
1458 TEST(ErasureCodeShec, encode_3)
1459 {
1460   ErasureCodeShecTableCache tcache;
1461   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1462                                   tcache,
1463                                   ErasureCodeShec::MULTIPLE);
1464   ErasureCodeProfile *profile = new ErasureCodeProfile();
1465   (*profile)["plugin"] = "shec";
1466   (*profile)["technique"] = "";
1467   (*profile)["crush-failure-domain"] = "osd";
1468   (*profile)["k"] = "4";
1469   (*profile)["m"] = "3";
1470   (*profile)["c"] = "2";
1471   shec->init(*profile, &cerr);
1472
1473   bufferlist in;
1474   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1475             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1476   );
1477   set<int> want_to_encode;
1478   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1479     want_to_encode.insert(i);
1480   }
1481   want_to_encode.insert(10);
1482   want_to_encode.insert(11);
1483   map<int, bufferlist> encoded;
1484   int r = shec->encode(want_to_encode, in, &encoded);
1485   EXPECT_EQ(0, r);
1486   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1487   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1488
1489   //decode
1490   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1491   map<int, bufferlist> decoded;
1492   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
1493                    &decoded);
1494   EXPECT_TRUE(shec->matrix != NULL);
1495   EXPECT_EQ(0, r);
1496   EXPECT_EQ(2u, decoded.size());
1497   EXPECT_EQ(shec->get_chunk_size(in.length()), decoded[0].length());
1498
1499   bufferlist out1, out2, usable;
1500   //out1 is "encoded"
1501   for (unsigned int i = 0; i < encoded.size(); ++i) {
1502     out1.append(encoded[i]);
1503   }
1504   //out2 is "decoded"
1505   shec->decode_concat(encoded, &out2);
1506   usable.substr_of(out2, 0, in.length());
1507   EXPECT_FALSE(out1 == in);
1508   EXPECT_TRUE(usable == in);
1509
1510   delete shec;
1511   delete profile;
1512 }
1513
1514 TEST(ErasureCodeShec, encode_4)
1515 {
1516   //init
1517   ErasureCodeShecTableCache tcache;
1518   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1519                                   tcache,
1520                                   ErasureCodeShec::MULTIPLE);
1521   ErasureCodeProfile *profile = new ErasureCodeProfile();
1522   (*profile)["plugin"] = "shec";
1523   (*profile)["technique"] = "";
1524   (*profile)["crush-failure-domain"] = "osd";
1525   (*profile)["k"] = "4";
1526   (*profile)["m"] = "3";
1527   (*profile)["c"] = "2";
1528   shec->init(*profile, &cerr);
1529
1530   //encode
1531   bufferlist in;
1532   set<int> want_to_encode;
1533   map<int, bufferlist> encoded;
1534
1535   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1536             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1537   );
1538   for (unsigned int i = 0; i < shec->get_chunk_count() - 1; ++i) {
1539     want_to_encode.insert(i);
1540   }
1541   want_to_encode.insert(100);
1542
1543   int r = shec->encode(want_to_encode, in, &encoded);
1544   EXPECT_EQ(0, r);
1545   EXPECT_EQ(shec->get_chunk_count()-1, encoded.size());
1546   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1547
1548   //decode
1549   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1550   map<int, bufferlist> decoded;
1551   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
1552                    &decoded);
1553   EXPECT_TRUE(shec->matrix != NULL);
1554   EXPECT_EQ(0, r);
1555   EXPECT_EQ(2u, decoded.size());
1556   EXPECT_EQ(shec->get_chunk_size(in.length()), decoded[0].length());
1557
1558   bufferlist out1, out2, usable;
1559   //out1 is "encoded"
1560   for (unsigned int i = 0; i < encoded.size(); ++i) {
1561     out1.append(encoded[i]);
1562   }
1563   //out2 is "decoded"
1564   shec->decode_concat(encoded, &out2);
1565   usable.substr_of(out2, 0, in.length());
1566   EXPECT_FALSE(out1 == in);
1567   EXPECT_TRUE(usable == in);
1568
1569   delete shec;
1570   delete profile;
1571 }
1572
1573 TEST(ErasureCodeShec, encode_8)
1574 {
1575   //init
1576   ErasureCodeShecTableCache tcache;
1577   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1578                                   tcache,
1579                                   ErasureCodeShec::MULTIPLE);
1580   ErasureCodeProfile *profile = new ErasureCodeProfile();
1581   (*profile)["plugin"] = "shec";
1582   (*profile)["technique"] = "";
1583   (*profile)["crush-failure-domain"] = "osd";
1584   (*profile)["k"] = "4";
1585   (*profile)["m"] = "3";
1586   (*profile)["c"] = "2";
1587   shec->init(*profile, &cerr);
1588
1589   //encode
1590   bufferlist in;
1591   set<int> want_to_encode;
1592
1593   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1594             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1595   );
1596   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1597     want_to_encode.insert(i);
1598   }
1599
1600   int r = shec->encode(want_to_encode, in, NULL);       //encoded = NULL
1601   EXPECT_EQ(-EINVAL, r);
1602
1603   delete shec;
1604   delete profile;
1605 }
1606
1607 TEST(ErasureCodeShec, encode_9)
1608 {
1609   //init
1610   ErasureCodeShecTableCache tcache;
1611   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1612                                   tcache,
1613                                   ErasureCodeShec::MULTIPLE);
1614   ErasureCodeProfile *profile = new ErasureCodeProfile();
1615   (*profile)["plugin"] = "shec";
1616   (*profile)["technique"] = "";
1617   (*profile)["crush-failure-domain"] = "osd";
1618   (*profile)["k"] = "4";
1619   (*profile)["m"] = "3";
1620   (*profile)["c"] = "2";
1621   shec->init(*profile, &cerr);
1622
1623   //encode
1624   bufferlist in;
1625   set<int> want_to_encode;
1626   map<int, bufferlist> encoded;
1627
1628   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1629             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1630   );
1631   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1632     want_to_encode.insert(i);
1633   }
1634   for (int i = 0; i < 100; ++i) {
1635     encoded[i].append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
1636   }
1637
1638   int r = shec->encode(want_to_encode, in, &encoded);
1639   EXPECT_EQ(-EINVAL, r);
1640
1641   delete shec;
1642   delete profile;
1643 }
1644
1645 TEST(ErasureCodeShec, encode2_1)
1646 {
1647   //init
1648   ErasureCodeShecTableCache tcache;
1649   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1650                                   tcache,
1651                                   ErasureCodeShec::MULTIPLE);
1652   ErasureCodeProfile *profile = new ErasureCodeProfile();
1653   (*profile)["plugin"] = "shec";
1654   (*profile)["technique"] = "";
1655   (*profile)["crush-failure-domain"] = "osd";
1656   (*profile)["k"] = "4";
1657   (*profile)["m"] = "3";
1658   (*profile)["c"] = "2";
1659   shec->init(*profile, &cerr);
1660
1661   //encode
1662   bufferlist in;
1663   set<int> want_to_encode;
1664   map<int, bufferlist> encoded;
1665
1666   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1667             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1668             "0123"//128
1669   );
1670   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1671     want_to_encode.insert(i);
1672   }
1673
1674   int r = shec->encode(want_to_encode, in, &encoded);
1675   EXPECT_EQ(0, r);
1676   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1677   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1678
1679   //decode
1680   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1681   map<int, bufferlist> decoded;
1682   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
1683                    &decoded);
1684   EXPECT_TRUE(shec->matrix != NULL);
1685   EXPECT_EQ(0, r);
1686   EXPECT_EQ(2u, decoded.size());
1687   EXPECT_EQ(32u, decoded[0].length());
1688
1689   bufferlist out1, out2, usable;
1690   //out1 is "encoded"
1691   for (unsigned int i = 0; i < encoded.size(); ++i) {
1692     out1.append(encoded[i]);
1693   }
1694   //out2 is "decoded"
1695   shec->decode_concat(encoded, &out2);
1696   usable.substr_of(out2, 0, in.length());
1697   EXPECT_FALSE(out1 == in);
1698   EXPECT_TRUE(usable == in);
1699
1700   delete shec;
1701   delete profile;
1702 }
1703
1704 TEST(ErasureCodeShec, encode2_3)
1705 {
1706   //init
1707   ErasureCodeShecTableCache tcache;
1708   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1709                                   tcache,
1710                                   ErasureCodeShec::MULTIPLE);
1711   ErasureCodeProfile *profile = new ErasureCodeProfile();
1712   (*profile)["plugin"] = "shec";
1713   (*profile)["technique"] = "";
1714   (*profile)["crush-failure-domain"] = "osd";
1715   (*profile)["k"] = "4";
1716   (*profile)["m"] = "3";
1717   (*profile)["c"] = "2";
1718   shec->init(*profile, &cerr);
1719
1720   //encode
1721   bufferlist in;
1722   set<int> want_to_encode;
1723   map<int, bufferlist> encoded;
1724
1725   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1726             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1727             "0123"//128
1728   );
1729   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1730     want_to_encode.insert(i);
1731   }
1732
1733   pthread_t tid;
1734   g_flag = 0;
1735   pthread_create(&tid, NULL, thread4, shec);
1736   while (g_flag == 0) {
1737     usleep(1);
1738   }
1739   sleep(1);
1740   printf("*** test start ***\n");
1741   int r = shec->encode(want_to_encode, in, &encoded);
1742   EXPECT_EQ(0, r);
1743   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1744   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1745   printf("*** test end ***\n");
1746   g_flag = 0;
1747   pthread_join(tid, NULL);
1748
1749   //decode
1750   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1751   map<int, bufferlist> decoded;
1752
1753   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
1754                    &decoded);
1755   EXPECT_TRUE(shec->matrix != NULL);
1756   EXPECT_EQ(0, r);
1757   EXPECT_EQ(2u, decoded.size());
1758   EXPECT_EQ(32u, decoded[0].length());
1759
1760   bufferlist out1, out2, usable;
1761   //out1 is "encoded"
1762   for (unsigned int i = 0; i < encoded.size(); ++i) {
1763     out1.append(encoded[i]);
1764   }
1765   //out2 is "decoded"
1766   shec->decode_concat(encoded, &out2);
1767   usable.substr_of(out2, 0, in.length());
1768   EXPECT_FALSE(out1 == in);
1769   EXPECT_TRUE(usable == in);
1770
1771   delete shec;
1772   delete profile;
1773 }
1774
1775 TEST(ErasureCodeShec, decode_1)
1776 {
1777   //init
1778   ErasureCodeShecTableCache tcache;
1779   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1780                                   tcache,
1781                                   ErasureCodeShec::MULTIPLE);
1782   ErasureCodeProfile *profile = new ErasureCodeProfile();
1783   (*profile)["plugin"] = "shec";
1784   (*profile)["technique"] = "";
1785   (*profile)["crush-failure-domain"] = "osd";
1786   (*profile)["k"] = "4";
1787   (*profile)["m"] = "3";
1788   (*profile)["c"] = "2";
1789   shec->init(*profile, &cerr);
1790
1791   //encode
1792   bufferlist in;
1793   set<int> want_to_encode;
1794   map<int, bufferlist> encoded;
1795
1796   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1797             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1798             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
1799             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
1800   );
1801   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1802     want_to_encode.insert(i);
1803   }
1804
1805   int r = shec->encode(want_to_encode, in, &encoded);
1806   EXPECT_EQ(0, r);
1807   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1808   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1809
1810   // all chunks are available
1811   //decode
1812   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
1813   map<int, bufferlist> decoded;
1814
1815   r = shec->decode(set<int>(want_to_decode, want_to_decode + 7), encoded,
1816                    &decoded);
1817   EXPECT_TRUE(shec->matrix != NULL);
1818   EXPECT_EQ(0, r);
1819   EXPECT_EQ(7u, decoded.size());
1820
1821   bufferlist usable;
1822   int cmp;
1823   unsigned int c_size = shec->get_chunk_size(in.length());
1824   for (unsigned int i = 0; i < shec->get_data_chunk_count(); ++i) {
1825     usable.clear();
1826     EXPECT_EQ(c_size, decoded[i].length());
1827     if ( c_size * (i+1) <= in.length() ) {
1828       usable.substr_of(in, c_size * i, c_size);
1829       cmp = memcmp(decoded[i].c_str(), usable.c_str(), c_size);
1830     } else {
1831       usable.substr_of(in, c_size * i, in.length() % c_size);
1832       cmp = memcmp(decoded[i].c_str(), usable.c_str(), in.length() % c_size);
1833     }
1834     EXPECT_EQ(0, cmp);
1835   }
1836
1837   delete shec;
1838   delete profile;
1839 }
1840
1841 TEST(ErasureCodeShec, decode_8)
1842 {
1843   //init
1844   ErasureCodeShecTableCache tcache;
1845   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1846                                   tcache,
1847                                   ErasureCodeShec::MULTIPLE);
1848   ErasureCodeProfile *profile = new ErasureCodeProfile();
1849   (*profile)["plugin"] = "shec";
1850   (*profile)["technique"] = "";
1851   (*profile)["crush-failure-domain"] = "osd";
1852   (*profile)["k"] = "4";
1853   (*profile)["m"] = "3";
1854   (*profile)["c"] = "2";
1855   shec->init(*profile, &cerr);
1856
1857   //encode
1858   bufferlist in;
1859   set<int> want_to_encode;
1860   map<int, bufferlist> encoded;
1861
1862   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1863             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1864             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
1865             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
1866   );
1867   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1868     want_to_encode.insert(i);
1869   }
1870
1871   int r = shec->encode(want_to_encode, in, &encoded);
1872   EXPECT_EQ(0, r);
1873   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1874   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1875
1876   // all chunks are available
1877   //decode
1878   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; //more than k+m
1879   map<int, bufferlist> decoded;
1880
1881   r = shec->decode(set<int>(want_to_decode, want_to_decode + 8), encoded,
1882                    &decoded);
1883   EXPECT_EQ(0, r);
1884   EXPECT_EQ(7u, decoded.size());
1885   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1886
1887   bufferlist usable;
1888   int cmp;
1889   unsigned int c_size = shec->get_chunk_size(in.length());
1890   for (unsigned int i = 0; i < shec->get_data_chunk_count(); ++i) {
1891     usable.clear();
1892     EXPECT_EQ(c_size, decoded[i].length());
1893     if ( c_size * (i+1) <= in.length() ) {
1894       usable.substr_of(in, c_size * i, c_size);
1895       cmp = memcmp(decoded[i].c_str(), usable.c_str(), c_size);
1896     } else {
1897       usable.substr_of(in, c_size * i, in.length() % c_size);
1898       cmp = memcmp(decoded[i].c_str(), usable.c_str(), in.length() % c_size);
1899     }
1900     EXPECT_EQ(0, cmp);
1901   }
1902
1903   delete shec;
1904   delete profile;
1905 }
1906
1907 TEST(ErasureCodeShec, decode_9)
1908 {
1909   //init
1910   ErasureCodeShecTableCache tcache;
1911   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1912                                   tcache,
1913                                   ErasureCodeShec::MULTIPLE);
1914   ErasureCodeProfile *profile = new ErasureCodeProfile();
1915   (*profile)["plugin"] = "shec";
1916   (*profile)["technique"] = "";
1917   (*profile)["crush-failure-domain"] = "osd";
1918   (*profile)["k"] = "4";
1919   (*profile)["m"] = "3";
1920   (*profile)["c"] = "2";
1921   shec->init(*profile, &cerr);
1922
1923   //encode
1924   bufferlist in;
1925   set<int> want_to_encode;
1926   map<int, bufferlist> encoded;
1927
1928   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
1929             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
1930             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
1931             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
1932   );
1933   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
1934     want_to_encode.insert(i);
1935   }
1936
1937   int r = shec->encode(want_to_encode, in, &encoded);
1938   EXPECT_EQ(0, r);
1939   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
1940   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
1941
1942   // all chunks are available
1943   //decode
1944   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
1945   map<int, bufferlist> decoded;
1946
1947   //extra data
1948   bufferlist buf;
1949   buf.append("abc");
1950   encoded[100] = buf;
1951
1952   r = shec->decode(set<int>(want_to_decode, want_to_decode + 10), encoded,
1953                    &decoded);
1954   EXPECT_TRUE(shec->matrix != NULL);
1955   EXPECT_EQ(0, r);
1956   EXPECT_EQ(7u, decoded.size());
1957   EXPECT_EQ(shec->get_chunk_size(in.length()), decoded[0].length());
1958
1959   bufferlist out1, usable;
1960   //out1 is "encoded"
1961   for (unsigned int i = 0; i < encoded.size(); ++i) {
1962     out1.append(encoded[i]);
1963   }
1964   EXPECT_FALSE(out1 == in);
1965   //usable is "decoded"
1966   int cmp;
1967   unsigned int c_size = shec->get_chunk_size(in.length());
1968   for (unsigned int i = 0; i < shec->get_data_chunk_count(); ++i) {
1969     usable.clear();
1970     EXPECT_EQ(c_size, decoded[i].length());
1971     if ( c_size * (i+1) <= in.length() ) {
1972       usable.substr_of(in, c_size * i, c_size);
1973       cmp = memcmp(decoded[i].c_str(), usable.c_str(), c_size);
1974     } else {
1975       usable.substr_of(in, c_size * i, in.length() % c_size);
1976       cmp = memcmp(decoded[i].c_str(), usable.c_str(), in.length() % c_size);
1977     }
1978     EXPECT_EQ(0, cmp);
1979   }
1980
1981   delete shec;
1982   delete profile;
1983 }
1984
1985 TEST(ErasureCodeShec, decode_10)
1986 {
1987   //init
1988   ErasureCodeShecTableCache tcache;
1989   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
1990                                   tcache,
1991                                   ErasureCodeShec::MULTIPLE);
1992   ErasureCodeProfile *profile = new ErasureCodeProfile();
1993   (*profile)["plugin"] = "shec";
1994   (*profile)["technique"] = "";
1995   (*profile)["crush-failure-domain"] = "osd";
1996   (*profile)["k"] = "4";
1997   (*profile)["m"] = "3";
1998   (*profile)["c"] = "2";
1999   shec->init(*profile, &cerr);
2000
2001   //encode
2002   bufferlist in;
2003   set<int> want_to_encode;
2004   map<int, bufferlist> encoded;
2005
2006   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2007             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2008             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2009             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2010   );
2011   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2012     want_to_encode.insert(i);
2013   }
2014
2015   int r = shec->encode(want_to_encode, in, &encoded);
2016   EXPECT_EQ(0, r);
2017   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2018   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2019
2020   //decode
2021   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 }; //more than k+m
2022   map<int, bufferlist> decoded, inchunks;
2023
2024   for ( unsigned int i = 0; i < 3; ++i) {
2025     inchunks.insert(make_pair(i, encoded[i]));
2026   }
2027
2028   r = shec->decode(set<int>(want_to_decode, want_to_decode + 7), inchunks,
2029                    &decoded);
2030   EXPECT_EQ(-1, r);
2031
2032   delete shec;
2033   delete profile;
2034 }
2035
2036 TEST(ErasureCodeShec, decode_11)
2037 {
2038   //init
2039   ErasureCodeShecTableCache tcache;
2040   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2041                                   tcache,
2042                                   ErasureCodeShec::MULTIPLE);
2043   ErasureCodeProfile *profile = new ErasureCodeProfile();
2044   (*profile)["plugin"] = "shec";
2045   (*profile)["technique"] = "";
2046   (*profile)["crush-failure-domain"] = "osd";
2047   (*profile)["k"] = "4";
2048   (*profile)["m"] = "3";
2049   (*profile)["c"] = "2";
2050   shec->init(*profile, &cerr);
2051
2052   //encode
2053   bufferlist in;
2054   set<int> want_to_encode;
2055   map<int, bufferlist> encoded;
2056
2057   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2058             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2059             "ABCD"//128
2060   );
2061   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2062     want_to_encode.insert(i);
2063   }
2064
2065   int r = shec->encode(want_to_encode, in, &encoded);
2066   EXPECT_EQ(0, r);
2067   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2068   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2069
2070   //decode
2071   int want_to_decode[] = { 0, 1, 2, 3, 4 };
2072   map<int, bufferlist> decoded, inchunks;
2073
2074   for ( unsigned int i = 4; i < 7; ++i) {
2075     inchunks.insert(make_pair(i, encoded[i]));
2076   }
2077
2078   r = shec->decode(set<int>(want_to_decode, want_to_decode + 5), inchunks,
2079                    &decoded);
2080   EXPECT_EQ(-1, r);
2081
2082   delete shec;
2083   delete profile;
2084 }
2085
2086 TEST(ErasureCodeShec, decode_12)
2087 {
2088   //init
2089   ErasureCodeShecTableCache tcache;
2090   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2091                                   tcache,
2092                                   ErasureCodeShec::MULTIPLE);
2093   ErasureCodeProfile *profile = new ErasureCodeProfile();
2094   (*profile)["plugin"] = "shec";
2095   (*profile)["technique"] = "";
2096   (*profile)["crush-failure-domain"] = "osd";
2097   (*profile)["k"] = "4";
2098   (*profile)["m"] = "3";
2099   (*profile)["c"] = "2";
2100   shec->init(*profile, &cerr);
2101
2102   //encode
2103   bufferlist in;
2104   set<int> want_to_encode;
2105   map<int, bufferlist> encoded;
2106
2107   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2108             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2109             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2110             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2111   );
2112   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2113     want_to_encode.insert(i);
2114   }
2115
2116   int r = shec->encode(want_to_encode, in, &encoded);
2117   EXPECT_EQ(0, r);
2118   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2119   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2120
2121   // all chunks are available
2122   //decode
2123   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
2124
2125   //decoded = NULL
2126   r = shec->decode(set<int>(want_to_decode, want_to_decode + 7), encoded,
2127                    NULL);
2128   EXPECT_NE(0, r);
2129
2130   delete shec;
2131   delete profile;
2132 }
2133
2134 TEST(ErasureCodeShec, decode_13)
2135 {
2136   //init
2137   ErasureCodeShecTableCache tcache;
2138   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2139                                   tcache,
2140                                   ErasureCodeShec::MULTIPLE);
2141   ErasureCodeProfile *profile = new ErasureCodeProfile();
2142   (*profile)["plugin"] = "shec";
2143   (*profile)["technique"] = "";
2144   (*profile)["crush-failure-domain"] = "osd";
2145   (*profile)["k"] = "4";
2146   (*profile)["m"] = "3";
2147   (*profile)["c"] = "2";
2148   shec->init(*profile, &cerr);
2149
2150   //encode
2151   bufferlist in;
2152   set<int> want_to_encode;
2153   map<int, bufferlist> encoded;
2154
2155   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2156             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2157             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2158             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2159   );
2160   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2161     want_to_encode.insert(i);
2162   }
2163
2164   int r = shec->encode(want_to_encode, in, &encoded);
2165   EXPECT_EQ(0, r);
2166   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2167   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2168
2169   // all chunks are available
2170   //decode
2171   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6 };
2172   map<int, bufferlist> decoded;
2173
2174   //extra data
2175   bufferlist buf;
2176   buf.append("a");
2177   for (int i = 0; i < 100; ++i) {
2178     decoded[i] = buf;
2179   }
2180
2181   r = shec->decode(set<int>(want_to_decode, want_to_decode + 7), encoded,
2182                    &decoded);
2183   EXPECT_NE(0, r);
2184
2185   delete shec;
2186   delete profile;
2187 }
2188
2189 TEST(ErasureCodeShec, decode2_1)
2190 {
2191   //init
2192   ErasureCodeShecTableCache tcache;
2193   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2194                                   tcache,
2195                                   ErasureCodeShec::MULTIPLE);
2196   ErasureCodeProfile *profile = new ErasureCodeProfile();
2197   (*profile)["plugin"] = "shec";
2198   (*profile)["technique"] = "";
2199   (*profile)["crush-failure-domain"] = "osd";
2200   (*profile)["k"] = "4";
2201   (*profile)["m"] = "3";
2202   (*profile)["c"] = "2";
2203   shec->init(*profile, &cerr);
2204
2205   //encode
2206   bufferlist in;
2207   set<int> want_to_encode;
2208   map<int, bufferlist> encoded;
2209
2210   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2211             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2212             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2213             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2214   );
2215   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2216     want_to_encode.insert(i);
2217   }
2218
2219   int r = shec->encode(want_to_encode, in, &encoded);
2220   EXPECT_EQ(0, r);
2221   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2222   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2223
2224   // all chunks are available
2225   //decode
2226   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
2227   map<int, bufferlist> decoded;
2228
2229   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
2230                    &decoded);
2231   EXPECT_TRUE(shec->matrix != NULL);
2232   EXPECT_EQ(0, r);
2233   EXPECT_EQ(2u, decoded.size());
2234
2235   bufferlist out;
2236   shec->decode_concat(encoded, &out);
2237   bufferlist usable;
2238   usable.substr_of(out, 0, in.length());
2239   EXPECT_TRUE(usable == in);
2240
2241   delete shec;
2242   delete profile;
2243 }
2244
2245 TEST(ErasureCodeShec, decode2_3)
2246 {
2247   //init
2248   ErasureCodeShecTableCache tcache;
2249   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2250                                   tcache,
2251                                   ErasureCodeShec::MULTIPLE);
2252   ErasureCodeProfile *profile = new ErasureCodeProfile();
2253   (*profile)["plugin"] = "shec";
2254   (*profile)["technique"] = "";
2255   (*profile)["crush-failure-domain"] = "osd";
2256   (*profile)["k"] = "4";
2257   (*profile)["m"] = "3";
2258   (*profile)["c"] = "2";
2259   shec->init(*profile, &cerr);
2260
2261   //encode
2262   bufferlist in;
2263   set<int> want_to_encode;
2264   map<int, bufferlist> encoded;
2265
2266   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2267             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2268             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2269             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2270   );
2271   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2272     want_to_encode.insert(i);
2273   }
2274
2275   int r = shec->encode(want_to_encode, in, &encoded);
2276   EXPECT_EQ(0, r);
2277   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2278   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2279
2280   // all chunks are available
2281   //decode
2282   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
2283   map<int, bufferlist> decoded;
2284
2285   pthread_t tid;
2286   g_flag = 0;
2287   pthread_create(&tid, NULL, thread4, shec);
2288   while (g_flag == 0) {
2289     usleep(1);
2290   }
2291   sleep(1);
2292   printf("*** test start ***\n");
2293   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
2294                    &decoded);
2295   EXPECT_TRUE(shec->matrix != NULL);
2296   EXPECT_EQ(0, r);
2297   EXPECT_EQ(2u, decoded.size());
2298   printf("*** test end ***\n");
2299   g_flag = 0;
2300   pthread_join(tid, NULL);
2301
2302   bufferlist out;
2303   shec->decode_concat(encoded, &out);
2304   bufferlist usable;
2305   usable.substr_of(out, 0, in.length());
2306   EXPECT_TRUE(usable == in);
2307
2308   delete shec;
2309   delete profile;
2310 }
2311
2312 TEST(ErasureCodeShec, decode2_4)
2313 {
2314   //init
2315   ErasureCodeShecTableCache tcache;
2316   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2317                                   tcache,
2318                                   ErasureCodeShec::MULTIPLE);
2319   ErasureCodeProfile *profile = new ErasureCodeProfile();
2320   (*profile)["plugin"] = "shec";
2321   (*profile)["technique"] = "";
2322   (*profile)["crush-failure-domain"] = "osd";
2323   (*profile)["k"] = "4";
2324   (*profile)["m"] = "3";
2325   (*profile)["c"] = "2";
2326   shec->init(*profile, &cerr);
2327
2328   //encode
2329   bufferlist in;
2330   set<int> want_to_encode;
2331   map<int, bufferlist> encoded;
2332
2333   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2334             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2335             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2336             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2337   );
2338   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2339     want_to_encode.insert(i);
2340   }
2341
2342   int r = shec->encode(want_to_encode, in, &encoded);
2343   EXPECT_EQ(0, r);
2344   EXPECT_EQ(shec->get_chunk_count(), encoded.size());
2345   EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
2346
2347   //decode
2348   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
2349   map<int, bufferlist> decoded;
2350
2351   // cannot recover
2352   bufferlist out;
2353   map<int, bufferlist> degraded;
2354   degraded[0] = encoded[0];
2355
2356   r = shec->decode(set<int>(want_to_decode, want_to_decode + 2), degraded,
2357                    &decoded);
2358   EXPECT_EQ(-1, r);
2359
2360   delete shec;
2361   delete profile;
2362 }
2363
2364 TEST(ErasureCodeShec, create_rule_1_2)
2365 {
2366   //create ruleset
2367   CrushWrapper *crush = new CrushWrapper;
2368   crush->create();
2369   crush->set_type_name(2, "root");
2370   crush->set_type_name(1, "host");
2371   crush->set_type_name(0, "osd");
2372
2373   int rootno;
2374   crush->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1, 2, 0, NULL,
2375                     NULL, &rootno);
2376   crush->set_item_name(rootno, "default");
2377
2378   map < string, string > loc;
2379   loc["root"] = "default";
2380
2381   int num_host = 2;
2382   int num_osd = 5;
2383   int osd = 0;
2384   for (int h = 0; h < num_host; ++h) {
2385     loc["host"] = string("host-") + stringify(h);
2386     for (int o = 0; o < num_osd; ++o, ++osd) {
2387       crush->insert_item(g_ceph_context, osd, 1.0,
2388                          string("osd.") + stringify(osd), loc);
2389     }
2390   }
2391
2392   //init
2393   ErasureCodeShecTableCache tcache;
2394   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2395                                   tcache,
2396                                   ErasureCodeShec::MULTIPLE);
2397   ErasureCodeProfile *profile = new ErasureCodeProfile();
2398   (*profile)["plugin"] = "shec";
2399   (*profile)["technique"] = "";
2400   (*profile)["crush-failure-domain"] = "osd";
2401   (*profile)["k"] = "4";
2402   (*profile)["m"] = "3";
2403   (*profile)["c"] = "2";
2404   shec->init(*profile, &cerr);
2405
2406   //create_rule
2407   stringstream ss;
2408
2409   int r = shec->create_rule("myrule", *crush, &ss);
2410   EXPECT_EQ(0, r);
2411   EXPECT_STREQ("myrule", crush->rule_name_map[0].c_str());
2412
2413   //reexecute create_rule
2414   r = shec->create_rule("myrule", *crush, &ss);
2415   EXPECT_EQ(-EEXIST, r);
2416
2417   delete shec;
2418   delete profile;
2419   delete crush;
2420 }
2421
2422 TEST(ErasureCodeShec, create_rule_4)
2423 {
2424   //create ruleset
2425   CrushWrapper *crush = new CrushWrapper;
2426   crush->create();
2427   crush->set_type_name(2, "root");
2428   crush->set_type_name(1, "host");
2429   crush->set_type_name(0, "osd");
2430
2431   int rootno;
2432   crush->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1, 2, 0, NULL,
2433                     NULL, &rootno);
2434   crush->set_item_name(rootno, "default");
2435
2436   map < string, string > loc;
2437   loc["root"] = "default";
2438
2439   int num_host = 2;
2440   int num_osd = 5;
2441   int osd = 0;
2442   for (int h = 0; h < num_host; ++h) {
2443     loc["host"] = string("host-") + stringify(h);
2444     for (int o = 0; o < num_osd; ++o, ++osd) {
2445       crush->insert_item(g_ceph_context, osd, 1.0,
2446                          string("osd.") + stringify(osd), loc);
2447     }
2448   }
2449
2450   //init
2451   ErasureCodeShecTableCache tcache;
2452   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2453                                   tcache,
2454                                   ErasureCodeShec::MULTIPLE);
2455   ErasureCodeProfile *profile = new ErasureCodeProfile();
2456   (*profile)["plugin"] = "shec";
2457   (*profile)["technique"] = "";
2458   (*profile)["crush-failure-domain"] = "osd";
2459   (*profile)["k"] = "4";
2460   (*profile)["m"] = "3";
2461   (*profile)["c"] = "2";
2462   shec->init(*profile, &cerr);
2463
2464   //create_rule
2465   int r = shec->create_rule("myrule", *crush, NULL);    //ss = NULL
2466   EXPECT_EQ(0, r);
2467
2468   delete shec;
2469   delete profile;
2470   delete crush;
2471 }
2472
2473 TEST(ErasureCodeShec, create_rule2_1)
2474 {
2475   //create ruleset
2476   CrushWrapper *crush = new CrushWrapper;
2477   crush->create();
2478   crush->set_type_name(2, "root");
2479   crush->set_type_name(1, "host");
2480   crush->set_type_name(0, "osd");
2481
2482   int rootno;
2483   crush->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1, 2, 0, NULL,
2484                     NULL, &rootno);
2485   crush->set_item_name(rootno, "default");
2486
2487   map < string, string > loc;
2488   loc["root"] = "default";
2489
2490   int num_host = 2;
2491   int num_osd = 5;
2492   int osd = 0;
2493   for (int h = 0; h < num_host; ++h) {
2494     loc["host"] = string("host-") + stringify(h);
2495     for (int o = 0; o < num_osd; ++o, ++osd) {
2496       crush->insert_item(g_ceph_context, osd, 1.0,
2497                          string("osd.") + stringify(osd), loc);
2498     }
2499   }
2500
2501   //init
2502   ErasureCodeShecTableCache tcache;
2503   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2504                                   tcache,
2505                                   ErasureCodeShec::MULTIPLE);
2506   ErasureCodeProfile *profile = new ErasureCodeProfile();
2507   (*profile)["plugin"] = "shec";
2508   (*profile)["technique"] = "";
2509   (*profile)["crush-failure-domain"] = "osd";
2510   (*profile)["k"] = "4";
2511   (*profile)["m"] = "3";
2512   (*profile)["c"] = "2";
2513   shec->init(*profile, &cerr);
2514
2515   //create_rule
2516   stringstream ss;
2517
2518   int r = shec->create_rule("myrule", *crush, &ss);
2519   EXPECT_EQ(0, r);
2520   EXPECT_STREQ("myrule", crush->rule_name_map[0].c_str());
2521
2522   delete shec;
2523   delete profile;
2524   delete crush;
2525 }
2526
2527 struct CreateRuleset2_3_Param_d {
2528   ErasureCodeShec *shec;
2529   CrushWrapper *crush;
2530 };
2531
2532 TEST(ErasureCodeShec, create_rule2_3)
2533 {
2534   //create ruleset
2535   CrushWrapper *crush = new CrushWrapper;
2536   crush->create();
2537   crush->set_type_name(2, "root");
2538   crush->set_type_name(1, "host");
2539   crush->set_type_name(0, "osd");
2540
2541   int rootno;
2542   crush->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1, 2, 0, NULL,
2543                     NULL, &rootno);
2544   crush->set_item_name(rootno, "default");
2545
2546   map < string, string > loc;
2547   loc["root"] = "default";
2548
2549   int num_host = 2;
2550   int num_osd = 5;
2551   int osd = 0;
2552   for (int h = 0; h < num_host; ++h) {
2553     loc["host"] = string("host-") + stringify(h);
2554     for (int o = 0; o < num_osd; ++o, ++osd) {
2555       crush->insert_item(g_ceph_context, osd, 1.0,
2556                          string("osd.") + stringify(osd), loc);
2557     }
2558   }
2559
2560   //init
2561   ErasureCodeShecTableCache tcache;
2562   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2563                                   tcache,
2564                                   ErasureCodeShec::MULTIPLE);
2565   ErasureCodeProfile *profile = new ErasureCodeProfile();
2566   (*profile)["plugin"] = "shec";
2567   (*profile)["technique"] = "";
2568   (*profile)["crush-failure-domain"] = "osd";
2569   (*profile)["k"] = "4";
2570   (*profile)["m"] = "3";
2571   (*profile)["c"] = "2";
2572   shec->init(*profile, &cerr);
2573
2574   //create_rule
2575   stringstream ss;
2576
2577   pthread_t tid;
2578   g_flag = 0;
2579   pthread_create(&tid, NULL, thread3, shec);
2580   while (g_flag == 0) {
2581     usleep(1);
2582   }
2583   sleep(1);
2584   printf("*** test start ***\n");
2585   int r = (shec->create_rule("myrule", *crush, &ss));
2586   EXPECT_TRUE(r >= 0);
2587   printf("*** test end ***\n");
2588   g_flag = 0;
2589   pthread_join(tid, NULL);
2590
2591   delete shec;
2592   delete profile;
2593   delete crush;
2594 }
2595
2596 TEST(ErasureCodeShec, get_chunk_count_1)
2597 {
2598   //init
2599   ErasureCodeShecTableCache tcache;
2600   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2601                                   tcache,
2602                                   ErasureCodeShec::MULTIPLE);
2603   ErasureCodeProfile *profile = new ErasureCodeProfile();
2604   (*profile)["plugin"] = "shec";
2605   (*profile)["technique"] = "";
2606   (*profile)["crush-failure-domain"] = "osd";
2607   (*profile)["k"] = "4";
2608   (*profile)["m"] = "3";
2609   (*profile)["c"] = "2";
2610   shec->init(*profile, &cerr);
2611
2612   //get_chunk_count
2613   EXPECT_EQ(7u, shec->get_chunk_count());
2614
2615   delete shec;
2616   delete profile;
2617 }
2618
2619 TEST(ErasureCodeShec, get_data_chunk_count_1)
2620 {
2621   //init
2622   ErasureCodeShecTableCache tcache;
2623   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2624                                   tcache,
2625                                   ErasureCodeShec::MULTIPLE);
2626   ErasureCodeProfile *profile = new ErasureCodeProfile();
2627   (*profile)["plugin"] = "shec";
2628   (*profile)["technique"] = "";
2629   (*profile)["crush-failure-domain"] = "osd";
2630   (*profile)["k"] = "4";
2631   (*profile)["m"] = "3";
2632   (*profile)["c"] = "2";
2633   shec->init(*profile, &cerr);
2634
2635   //get_data_chunk_count
2636   EXPECT_EQ(4u, shec->get_data_chunk_count());
2637
2638   delete shec;
2639   delete profile;
2640 }
2641
2642 TEST(ErasureCodeShec, get_chunk_size_1_2)
2643 {
2644   //init
2645   ErasureCodeShecTableCache tcache;
2646   ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
2647                                   tcache,
2648                                   ErasureCodeShec::MULTIPLE);
2649   ErasureCodeProfile *profile = new ErasureCodeProfile();
2650   (*profile)["plugin"] = "shec";
2651   (*profile)["technique"] = "";
2652   (*profile)["crush-failure-domain"] = "osd";
2653   (*profile)["k"] = "4";
2654   (*profile)["m"] = "3";
2655   (*profile)["c"] = "2";
2656   (*profile)["w"] = "8";
2657   shec->init(*profile, &cerr);
2658
2659   //when there is no padding(128=k*w*4)
2660   EXPECT_EQ(32u, shec->get_chunk_size(128));
2661   //when there is padding(126=k*w*4-2)
2662   EXPECT_EQ(32u, shec->get_chunk_size(126));
2663
2664   delete shec;
2665   delete profile;
2666 }
2667
2668 void* thread1(void* pParam)
2669 {
2670   ErasureCodeShec* shec = (ErasureCodeShec*) pParam;
2671   set<int> want_to_decode;
2672   set<int> available_chunks;
2673   set<int> minimum_chunks;
2674
2675   want_to_decode.insert(0);
2676   want_to_decode.insert(1);
2677   available_chunks.insert(0);
2678   available_chunks.insert(1);
2679   available_chunks.insert(2);
2680
2681   printf("*** thread loop start ***\n");
2682   g_flag = 1;
2683   while (g_flag == 1) {
2684     shec->minimum_to_decode(want_to_decode, available_chunks, &minimum_chunks);
2685   }
2686   printf("*** thread loop end ***\n");
2687
2688   return NULL;
2689 }
2690
2691 void* thread2(void* pParam)
2692 {
2693   ErasureCodeShec* shec = (ErasureCodeShec*) pParam;
2694   set<int> want_to_decode;
2695   map<int, int> available_chunks;
2696   set<int> minimum_chunks;
2697
2698   want_to_decode.insert(0);
2699   want_to_decode.insert(1);
2700   available_chunks[0] = 0;
2701   available_chunks[1] = 1;
2702   available_chunks[2] = 2;
2703
2704   printf("*** thread loop start ***\n");
2705   g_flag = 1;
2706   while (g_flag == 1) {
2707     shec->minimum_to_decode_with_cost(want_to_decode, available_chunks,
2708                                       &minimum_chunks);
2709     minimum_chunks.clear();
2710   }
2711   printf("*** thread loop end ***\n");
2712
2713   return NULL;
2714 }
2715
2716 void* thread3(void* pParam)
2717 {
2718   ErasureCodeShec* shec = (ErasureCodeShec*) pParam;
2719
2720   CrushWrapper *crush = new CrushWrapper;
2721   crush->create();
2722   crush->set_type_name(2, "root");
2723   crush->set_type_name(1, "host");
2724   crush->set_type_name(0, "osd");
2725
2726   int rootno;
2727   crush->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1, 2, 0, NULL,
2728                     NULL, &rootno);
2729   crush->set_item_name(rootno, "default");
2730
2731   map < string, string > loc;
2732   loc["root"] = "default";
2733
2734   int num_host = 2;
2735   int num_osd = 5;
2736   int osd = 0;
2737   for (int h = 0; h < num_host; ++h) {
2738     loc["host"] = string("host-") + stringify(h);
2739     for (int o = 0; o < num_osd; ++o, ++osd) {
2740       crush->insert_item(g_ceph_context, osd, 1.0,
2741                          string("osd.") + stringify(osd), loc);
2742     }
2743   }
2744
2745   stringstream ss;
2746   int i = 0;
2747   char name[30];
2748
2749   printf("*** thread loop start ***\n");
2750   g_flag = 1;
2751   while (g_flag == 1) {
2752     sprintf(name, "myrule%d", i);
2753     shec->create_rule(name, *crush, &ss);
2754     ++i;
2755   }
2756   printf("*** thread loop end ***\n");
2757
2758   return NULL;
2759 }
2760
2761 void* thread4(void* pParam)
2762 {
2763   ErasureCodeShec* shec = (ErasureCodeShec*) pParam;
2764
2765   bufferlist in;
2766   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2767             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2768             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2769             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2770   );
2771   set<int> want_to_encode;
2772   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2773     want_to_encode.insert(i);
2774   }
2775
2776   map<int, bufferlist> encoded;
2777
2778   printf("*** thread loop start ***\n");
2779   g_flag = 1;
2780   while (g_flag == 1) {
2781     shec->encode(want_to_encode, in, &encoded);
2782     encoded.clear();
2783   }
2784   printf("*** thread loop end ***\n");
2785
2786   return NULL;
2787 }
2788
2789 void* thread5(void* pParam)
2790 {
2791   ErasureCodeShec* shec = (ErasureCodeShec*) pParam;
2792
2793   bufferlist in;
2794   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//length = 62
2795           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
2796           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
2797           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//248
2798           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//310
2799   );
2800   set<int> want_to_encode;
2801   for (unsigned int i = 0; i < shec->get_chunk_count(); ++i) {
2802     want_to_encode.insert(i);
2803   }
2804   map<int, bufferlist> encoded;
2805   shec->encode(want_to_encode, in, &encoded);
2806
2807   int want_to_decode[] = { 0, 1, 2, 3, 4, 5 };
2808   map<int, bufferlist> decoded;
2809
2810   printf("*** thread loop start ***\n");
2811   g_flag = 1;
2812   while (g_flag == 1) {
2813     shec->decode(set<int>(want_to_decode, want_to_decode + 2), encoded,
2814                  &decoded);
2815     decoded.clear();
2816   }
2817   printf("*** thread loop end ***\n");
2818
2819   return NULL;
2820 }