1 package org.apache.helix;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.StringReader;
24 import java.io.StringWriter;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.apache.helix.ZNRecord;
32 import org.apache.helix.tools.IdealCalculatorByConsistentHashing;
33 import org.apache.helix.tools.IdealStateCalculatorByRush;
34 import org.apache.helix.tools.IdealStateCalculatorByShuffling;
35 import org.codehaus.jackson.JsonGenerationException;
36 import org.codehaus.jackson.map.JsonMappingException;
37 import org.codehaus.jackson.map.ObjectMapper;
38 import org.testng.Assert;
39 import org.testng.AssertJUnit;
40 import org.testng.annotations.Test;
41
42
43 public class TestShuffledIdealState
44 {
45 @Test ()
46 public void testInvocation() throws Exception
47 {
48 int partitions = 6, replicas = 2;
49 String dbName = "espressoDB1";
50 List<String> instanceNames = new ArrayList<String>();
51 instanceNames.add("localhost_1231");
52 instanceNames.add("localhost_1232");
53 instanceNames.add("localhost_1233");
54 instanceNames.add("localhost_1234");
55
56 ZNRecord result = IdealStateCalculatorByShuffling.calculateIdealState(
57 instanceNames, partitions, replicas, dbName);
58 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
59 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
60
61 ZNRecord result2 = IdealStateCalculatorByRush.calculateIdealState(instanceNames, 1, partitions, replicas, dbName);
62
63 ZNRecord result3 = IdealCalculatorByConsistentHashing.calculateIdealState(instanceNames, partitions, replicas, dbName, new IdealCalculatorByConsistentHashing.FnvHash());
64 IdealCalculatorByConsistentHashing.printIdealStateStats(result3, "MASTER");
65 IdealCalculatorByConsistentHashing.printIdealStateStats(result3, "SLAVE");
66 IdealCalculatorByConsistentHashing.printIdealStateStats(result3, "");
67 IdealCalculatorByConsistentHashing.printNodeOfflineOverhead(result3);
68
69
70 ObjectMapper mapper = new ObjectMapper();
71
72
73 StringWriter sw = new StringWriter();
74 try
75 {
76 mapper.writeValue(sw, result);
77
78
79 ZNRecord zn = mapper.readValue(new StringReader(sw.toString()),
80 ZNRecord.class);
81 System.out.println(result.toString());
82 System.out.println(zn.toString());
83 AssertJUnit.assertTrue(zn.toString().equalsIgnoreCase(result.toString()));
84 System.out.println();
85
86 sw= new StringWriter();
87 mapper.writeValue(sw, result2);
88
89 ZNRecord zn2 = mapper.readValue(new StringReader(sw.toString()),
90 ZNRecord.class);
91 System.out.println(result2.toString());
92 System.out.println(zn2.toString());
93 AssertJUnit.assertTrue(zn2.toString().equalsIgnoreCase(result2.toString()));
94
95 sw= new StringWriter();
96 mapper.writeValue(sw, result3);
97 System.out.println();
98
99 ZNRecord zn3 = mapper.readValue(new StringReader(sw.toString()),
100 ZNRecord.class);
101 System.out.println(result3.toString());
102 System.out.println(zn3.toString());
103 AssertJUnit.assertTrue(zn3.toString().equalsIgnoreCase(result3.toString()));
104 System.out.println();
105
106 } catch (JsonGenerationException e)
107 {
108
109 e.printStackTrace();
110 } catch (JsonMappingException e)
111 {
112
113 e.printStackTrace();
114 } catch (IOException e)
115 {
116
117 e.printStackTrace();
118 }
119 }
120
121 @Test
122 public void testShuffledIdealState()
123 {
124
125 int partitions = 6, replicas = 2, instances = 4;
126 String dbName = "espressoDB1";
127 List<String> instanceNames = new ArrayList<String>();
128 instanceNames.add("localhost_1231");
129 instanceNames.add("localhost_1232");
130 instanceNames.add("localhost_1233");
131 instanceNames.add("localhost_1234");
132
133 ZNRecord result = IdealStateCalculatorByShuffling.calculateIdealState(
134 instanceNames, partitions, replicas, dbName);
135 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
136 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
137 Assert.assertTrue(verify(result));
138
139
140 instanceNames.clear();
141 partitions = 4;
142 replicas = 3;
143 instances = 7;
144
145 for(int i = 0; i<instances; i++)
146 {
147 instanceNames.add("localhost_" + (1231 + i));
148 }
149 result = IdealStateCalculatorByShuffling.calculateIdealState(
150 instanceNames, partitions, replicas, dbName);
151 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
152 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
153 Assert.assertTrue(verify(result));
154
155
156 instanceNames.clear();
157 partitions = 14;
158 replicas = 3;
159 instances = 7;
160
161 for(int i = 0; i<instances; i++)
162 {
163 instanceNames.add("localhost_" + (1231 + i));
164 }
165 result = IdealStateCalculatorByShuffling.calculateIdealState(
166 instanceNames, partitions, replicas, dbName);
167 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
168 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
169 Assert.assertTrue(verify(result));
170
171
172 instanceNames.clear();
173 partitions = 4;
174 replicas = 3;
175 instances = 8;
176
177 for(int i = 0; i<instances; i++)
178 {
179 instanceNames.add("localhost_" + (1231 + i));
180 }
181 result = IdealStateCalculatorByShuffling.calculateIdealState(
182 instanceNames, partitions, replicas, dbName);
183 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
184 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
185 Assert.assertTrue(verify(result));
186
187
188 instanceNames.clear();
189 partitions = 4;
190 replicas = 3;
191 instances = 12;
192
193 for(int i = 0; i<instances; i++)
194 {
195 instanceNames.add("localhost_" + (1231 + i));
196 }
197 result = IdealStateCalculatorByShuffling.calculateIdealState(
198 instanceNames, partitions, replicas, dbName);
199 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
200 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
201 Assert.assertTrue(verify(result));
202
203
204 instanceNames.clear();
205 partitions = 4;
206 replicas = 2;
207 instances = 12;
208
209 for(int i = 0; i<instances; i++)
210 {
211 instanceNames.add("localhost_" + (1231 + i));
212 }
213 result = IdealStateCalculatorByShuffling.calculateIdealState(
214 instanceNames, partitions, replicas, dbName);
215 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
216 IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
217 Assert.assertTrue(verify(result));
218 }
219
220 boolean verify(ZNRecord result)
221 {
222 Map<String, Integer> masterPartitionCounts = new HashMap<String, Integer>();
223 Map<String, Integer> slavePartitionCounts = new HashMap<String, Integer>();
224
225 for(String key : result.getMapFields().keySet())
226 {
227 Map<String, String> mapField = result.getMapField(key);
228 int masterCount = 0;
229 for(String host: mapField.keySet())
230 {
231 if(mapField.get(host).equals("MASTER"))
232 {
233 Assert.assertTrue(masterCount == 0);
234 masterCount ++;
235 if(!masterPartitionCounts.containsKey(host))
236 {
237 masterPartitionCounts.put(host, 0);
238 }
239 else
240 {
241 masterPartitionCounts.put(host, masterPartitionCounts.get(host) + 1);
242 }
243 }
244 else
245 {
246 if(!slavePartitionCounts.containsKey(host))
247 {
248 slavePartitionCounts.put(host, 0);
249 }
250 else
251 {
252 slavePartitionCounts.put(host, slavePartitionCounts.get(host) + 1);
253 }
254 }
255 }
256 }
257
258 List<Integer> masterCounts = new ArrayList<Integer>();
259 List<Integer> slaveCounts = new ArrayList<Integer>();
260 masterCounts.addAll(masterPartitionCounts.values());
261 slaveCounts.addAll(slavePartitionCounts.values());
262 Collections.sort(masterCounts);
263 Collections.sort(slaveCounts);
264
265 Assert.assertTrue(masterCounts.get(masterCounts.size() - 1 ) - masterCounts.get(0) <= 1);
266
267 Assert.assertTrue(slaveCounts.get(slaveCounts.size() - 1 ) - slaveCounts.get(0) <= 2);
268 return true;
269 }
270 }