Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / erasure-code / TestErasureCodeShec_thread.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 executes some threads at the same time
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
35 class TestParam {
36 public:
37   string k, m, c, w;
38 };
39
40 TEST(ErasureCodeShec, thread)
41 {
42   TestParam param1, param2, param3, param4, param5;
43   param1.k = "6";
44   param1.m = "4";
45   param1.c = "3";
46   param1.w = "8";
47
48   param2.k = "4";
49   param2.m = "3";
50   param2.c = "2";
51   param2.w = "16";
52
53   param3.k = "10";
54   param3.m = "8";
55   param3.c = "4";
56   param3.w = "32";
57
58   param4.k = "5";
59   param4.m = "5";
60   param4.c = "5";
61   param4.w = "8";
62
63   param5.k = "9";
64   param5.m = "9";
65   param5.c = "6";
66   param5.w = "16";
67
68   pthread_t tid1, tid2, tid3, tid4, tid5;
69   pthread_create(&tid1, NULL, thread1, (void*) &param1);
70   std::cout << "thread1 start " << std::endl;
71   pthread_create(&tid2, NULL, thread1, (void*) &param2);
72   std::cout << "thread2 start " << std::endl;
73   pthread_create(&tid3, NULL, thread1, (void*) &param3);
74   std::cout << "thread3 start " << std::endl;
75   pthread_create(&tid4, NULL, thread1, (void*) &param4);
76   std::cout << "thread4 start " << std::endl;
77   pthread_create(&tid5, NULL, thread1, (void*) &param5);
78   std::cout << "thread5 start " << std::endl;
79
80   pthread_join(tid1, NULL);
81   pthread_join(tid2, NULL);
82   pthread_join(tid3, NULL);
83   pthread_join(tid4, NULL);
84   pthread_join(tid5, NULL);
85 }
86
87 void* thread1(void* pParam)
88 {
89   TestParam* param = static_cast<TestParam*>(pParam);
90
91   time_t start, end;
92
93   ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
94
95   instance.disable_dlclose = true;
96   {
97     Mutex::Locker l(instance.lock);
98     __erasure_code_init((char*) "shec", (char*) "");
99   }
100   std::cout << "__erasure_code_init finish " << std::endl;
101
102   //encode
103   bufferlist in;
104   set<int> want_to_encode;
105   map<int, bufferlist> encoded;
106
107   in.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" //length = 62
108             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//124
109             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"//186
110             "012345"//192
111   );
112
113   //decode
114   int want_to_decode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
115   map<int, bufferlist> decoded;
116   bufferlist out1, out2, usable;
117
118   time(&start);
119   time(&end);
120   const int kTestSec = 60;
121   ErasureCodeShecTableCache tcache;
122
123   while (kTestSec >= (end - start)) {
124     //init
125     int r;
126     ErasureCodeShec* shec = new ErasureCodeShecReedSolomonVandermonde(
127                                     tcache,
128                                     ErasureCodeShec::MULTIPLE);
129     ErasureCodeProfile *profile = new ErasureCodeProfile();
130     (*profile)["plugin"] = "shec";
131     (*profile)["technique"] = "multiple";
132     (*profile)["crush-failure-domain"] = "osd";
133     (*profile)["k"] = param->k;
134     (*profile)["m"] = param->m;
135     (*profile)["c"] = param->c;
136     (*profile)["w"] = param->w;
137     r = shec->init(*profile, &cerr);
138
139     int i_k = std::atoi(param->k.c_str());
140     int i_m = std::atoi(param->m.c_str());
141     int i_c = std::atoi(param->c.c_str());
142     int i_w = std::atoi(param->w.c_str());
143
144     EXPECT_EQ(0, r);
145     EXPECT_EQ(i_k, shec->k);
146     EXPECT_EQ(i_m, shec->m);
147     EXPECT_EQ(i_c, shec->c);
148     EXPECT_EQ(i_w, shec->w);
149     EXPECT_EQ(ErasureCodeShec::MULTIPLE, shec->technique);
150     EXPECT_STREQ("default", shec->rule_root.c_str());
151     EXPECT_STREQ("osd", shec->rule_failure_domain.c_str());
152     EXPECT_TRUE(shec->matrix != NULL);
153     if ((shec->matrix == NULL)) {
154       std::cout << "matrix is null" << std::endl;
155       // error
156       break;
157     }
158
159     //encode
160     for (unsigned int i = 0; i < shec->get_chunk_count(); i++) {
161       want_to_encode.insert(i);
162     }
163     r = shec->encode(want_to_encode, in, &encoded);
164
165     EXPECT_EQ(0, r);
166     EXPECT_EQ(shec->get_chunk_count(), encoded.size());
167     EXPECT_EQ(shec->get_chunk_size(in.length()), encoded[0].length());
168
169     if (r != 0) {
170       std::cout << "error in encode" << std::endl;
171       //error
172       break;
173     }
174
175     //decode
176     r = shec->decode(set<int>(want_to_decode, want_to_decode + 2),
177                      encoded,
178                      &decoded);
179
180     EXPECT_EQ(0, r);
181     EXPECT_EQ(2u, decoded.size());
182     EXPECT_EQ(shec->get_chunk_size(in.length()), decoded[0].length());
183
184     if (r != 0) {
185       std::cout << "error in decode" << std::endl;
186       //error
187       break;
188     }
189
190     //out1 is "encoded"
191     for (unsigned int i = 0; i < encoded.size(); i++) {
192       out1.append(encoded[i]);
193     }
194     //out2 is "decoded"
195     shec->decode_concat(encoded, &out2);
196     usable.substr_of(out2, 0, in.length());
197     EXPECT_FALSE(out1 == in);
198     EXPECT_TRUE(usable == in);
199     if (out1 == in || !(usable == in)) {
200       std::cout << "encode(decode) result is not correct" << std::endl;
201       break;
202     }
203
204     delete shec;
205     delete profile;
206     want_to_encode.clear();
207     encoded.clear();
208     decoded.clear();
209     out1.clear();
210     out2.clear();
211     usable.clear();
212
213     time(&end);
214   }
215
216   return NULL;
217 }