Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / erasure-code / TestErasureCodeExample.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 distributed storage system
5  *
6  * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
7  *
8  * Author: Loic Dachary <loic@dachary.org>
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  * 
15  */
16 #include <stdlib.h>
17
18 #include "include/stringify.h"
19 #include "ErasureCodeExample.h"
20 #include "global/global_context.h"
21 #include "gtest/gtest.h"
22
23 TEST(ErasureCodeExample, chunk_size)
24 {
25   ErasureCodeExample example;
26   EXPECT_EQ(3u, example.get_chunk_count());
27   EXPECT_EQ(11u, example.get_chunk_size(20));
28 }
29
30 TEST(ErasureCodeExample, minimum_to_decode)
31 {
32   ErasureCodeExample example;
33   set<int> available_chunks;
34   set<int> want_to_read;
35   want_to_read.insert(1);
36   {
37     set<int> minimum;
38     EXPECT_EQ(-EIO, example.minimum_to_decode(want_to_read,
39                                               available_chunks,
40                                               &minimum));
41   }
42   available_chunks.insert(0);
43   available_chunks.insert(2);
44   {
45     set<int> minimum;
46     EXPECT_EQ(0, example.minimum_to_decode(want_to_read,
47                                            available_chunks,
48                                            &minimum));
49     EXPECT_EQ(available_chunks, minimum);
50     EXPECT_EQ(2u, minimum.size());
51     EXPECT_EQ(1u, minimum.count(0));
52     EXPECT_EQ(1u, minimum.count(2));
53   }
54   {
55     set<int> minimum;
56     available_chunks.insert(1);
57     EXPECT_EQ(0, example.minimum_to_decode(want_to_read,
58                                            available_chunks,
59                                            &minimum));
60     EXPECT_EQ(1u, minimum.size());
61     EXPECT_EQ(1u, minimum.count(1));
62   }
63 }
64
65 TEST(ErasureCodeExample, minimum_to_decode_with_cost)
66 {
67   ErasureCodeExample example;
68   map<int,int> available;
69   set<int> want_to_read;
70   want_to_read.insert(1);
71   {
72     set<int> minimum;
73     EXPECT_EQ(-EIO, example.minimum_to_decode_with_cost(want_to_read,
74                                                         available,
75                                                         &minimum));
76   }
77   available[0] = 1;
78   available[2] = 1;
79   {
80     set<int> minimum;
81     EXPECT_EQ(0, example.minimum_to_decode_with_cost(want_to_read,
82                                                      available,
83                                                      &minimum));
84     EXPECT_EQ(2u, minimum.size());
85     EXPECT_EQ(1u, minimum.count(0));
86     EXPECT_EQ(1u, minimum.count(2));
87   }
88   {
89     set<int> minimum;
90     available[1] = 1;
91     EXPECT_EQ(0, example.minimum_to_decode_with_cost(want_to_read,
92                                                      available,
93                                                      &minimum));
94     EXPECT_EQ(1u, minimum.size());
95     EXPECT_EQ(1u, minimum.count(1));
96   }
97   {
98     set<int> minimum;
99     available[1] = 2;
100     EXPECT_EQ(0, example.minimum_to_decode_with_cost(want_to_read,
101                                                      available,
102                                                      &minimum));
103     EXPECT_EQ(2u, minimum.size());
104     EXPECT_EQ(1u, minimum.count(0));
105     EXPECT_EQ(1u, minimum.count(2));
106   }
107 }
108
109 TEST(ErasureCodeExample, encode_decode)
110 {
111   ErasureCodeExample example;
112
113   bufferlist in;
114   in.append("ABCDE");
115   set<int> want_to_encode;
116   for(unsigned int i = 0; i < example.get_chunk_count(); i++)
117     want_to_encode.insert(i);
118   map<int, bufferlist> encoded;
119   EXPECT_EQ(0, example.encode(want_to_encode, in, &encoded));
120   EXPECT_EQ(example.get_chunk_count(), encoded.size());
121   EXPECT_EQ(example.get_chunk_size(in.length()), encoded[0].length());
122   EXPECT_EQ('A', encoded[0][0]);
123   EXPECT_EQ('B', encoded[0][1]);
124   EXPECT_EQ('C', encoded[0][2]);
125   EXPECT_EQ('D', encoded[1][0]);
126   EXPECT_EQ('E', encoded[1][1]);
127   EXPECT_EQ('A'^'D', encoded[2][0]);
128   EXPECT_EQ('B'^'E', encoded[2][1]);
129   EXPECT_EQ('C'^0, encoded[2][2]);
130
131   // all chunks are available
132   {
133     int want_to_decode[] = { 0, 1 };
134     map<int, bufferlist> decoded;
135     EXPECT_EQ(0, example.decode(set<int>(want_to_decode, want_to_decode+2),
136                                 encoded,
137                                 &decoded));
138     EXPECT_EQ(2u, decoded.size());
139     EXPECT_EQ(3u, decoded[0].length());
140     EXPECT_EQ('A', decoded[0][0]);
141     EXPECT_EQ('B', decoded[0][1]);
142     EXPECT_EQ('C', decoded[0][2]);
143     EXPECT_EQ('D', decoded[1][0]);
144     EXPECT_EQ('E', decoded[1][1]);
145   }
146
147   // one chunk is missing 
148   {
149     map<int, bufferlist> degraded = encoded;
150     degraded.erase(0);
151     EXPECT_EQ(2u, degraded.size());
152     int want_to_decode[] = { 0, 1 };
153     map<int, bufferlist> decoded;
154     EXPECT_EQ(0, example.decode(set<int>(want_to_decode, want_to_decode+2),
155                                 degraded,
156                                 &decoded));
157     EXPECT_EQ(2u, decoded.size());
158     EXPECT_EQ(3u, decoded[0].length());
159     EXPECT_EQ('A', decoded[0][0]);
160     EXPECT_EQ('B', decoded[0][1]);
161     EXPECT_EQ('C', decoded[0][2]);
162     EXPECT_EQ('D', decoded[1][0]);
163     EXPECT_EQ('E', decoded[1][1]);
164   }
165 }
166
167 TEST(ErasureCodeExample, decode)
168 {
169   ErasureCodeExample example;
170
171 #define LARGE_ENOUGH 2048
172   bufferptr in_ptr(buffer::create_page_aligned(LARGE_ENOUGH));
173   in_ptr.zero();
174   in_ptr.set_length(0);
175   const char *payload =
176     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
177     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
178     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
179     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
180     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
181   in_ptr.append(payload, strlen(payload));
182   bufferlist in;
183   in.push_front(in_ptr);
184   int want_to_encode[] = { 0, 1, 2 };
185   map<int, bufferlist> encoded;
186   EXPECT_EQ(0, example.encode(set<int>(want_to_encode, want_to_encode+3),
187                               in,
188                               &encoded));
189   EXPECT_EQ(3u, encoded.size());
190
191   // successfull decode
192   bufferlist out;
193   EXPECT_EQ(0, example.decode_concat(encoded, &out));
194   bufferlist usable;
195   usable.substr_of(out, 0, in.length());
196   EXPECT_TRUE(usable == in);
197
198   // cannot recover
199   map<int, bufferlist> degraded;  
200   degraded[0] = encoded[0];
201   EXPECT_EQ(-ERANGE, example.decode_concat(degraded, &out));
202 }
203
204 TEST(ErasureCodeExample, create_rule)
205 {
206   CrushWrapper *c = new CrushWrapper;
207   c->create();
208   c->set_type_name(2, "root");
209   c->set_type_name(1, "host");
210   c->set_type_name(0, "osd");
211
212   int rootno;
213   c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
214                 5, 0, NULL, NULL, &rootno);
215   c->set_item_name(rootno, "default");
216
217   map<string,string> loc;
218   loc["root"] = "default";
219
220   int num_host = 2;
221   int num_osd = 5;
222   int osd = 0;
223   for (int h=0; h<num_host; ++h) {
224     loc["host"] = string("host-") + stringify(h);
225     for (int o=0; o<num_osd; ++o, ++osd) {
226       c->insert_item(g_ceph_context, osd, 1.0, string("osd.") + stringify(osd), loc);
227     }
228   }
229
230   stringstream ss;
231   ErasureCodeExample example;
232   EXPECT_EQ(0, example.create_rule("myrule", *c, &ss));
233 }
234
235 /*
236  * Local Variables:
237  * compile-command: "cd ../.. ; 
238  *   make -j4 && 
239  *   make unittest_erasure_code_example && 
240  *   valgrind  --leak-check=full --tool=memcheck \
241  *      ./unittest_erasure_code_example --gtest_filter=*.* \
242  *      --log-to-stderr=true --debug-osd=20
243  * "
244  * End:
245  */
246