]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: move two crush tests over 3384/head
authorSage Weil <sage@redhat.com>
Fri, 16 Jan 2015 05:10:31 +0000 (21:10 -0800)
committerSage Weil <sage@redhat.com>
Fri, 16 Jan 2015 05:10:31 +0000 (21:10 -0800)
CrushWrapper handles map manipulation, crush.cc tests the placement.

Signed-off-by: Sage Weil <sage@redhat.com>
src/test/crush/CrushWrapper.cc
src/test/crush/crush.cc

index b735b8469dd69b081de37031c53baaf5e906bd1d..c690ada4f16768511e5910ad67c5ab02f0162aed 100644 (file)
@@ -68,166 +68,6 @@ TEST(CrushWrapper, get_immediate_parent) {
   delete c;
 }
 
-TEST(CrushWrapper, straw_zero) {
-  // zero weight items should have no effect on placement.
-
-  CrushWrapper *c = new CrushWrapper;
-  const int ROOT_TYPE = 1;
-  c->set_type_name(ROOT_TYPE, "root");
-  const int OSD_TYPE = 0;
-  c->set_type_name(OSD_TYPE, "osd");
-
-  int n = 5;
-  int items[n], weights[n];
-  for (int i=0; i <n; ++i) {
-    items[i] = i;
-    weights[i] = 0x10000 * (n-i-1);
-  }
-
-  c->set_max_devices(n);
-
-  string root_name0("root0");
-  int root0;
-  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
-                            ROOT_TYPE, n, items, weights, &root0));
-  EXPECT_EQ(0, c->set_item_name(root0, root_name0));
-
-  string name0("rule0");
-  int ruleset0 = c->add_simple_ruleset(name0, root_name0, "osd",
-                                      "firstn", pg_pool_t::TYPE_REPLICATED);
-  EXPECT_EQ(0, ruleset0);
-
-  string root_name1("root1");
-  int root1;
-  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
-                            ROOT_TYPE, n-1, items, weights, &root1));
-  EXPECT_EQ(0, c->set_item_name(root1, root_name1));
-
-  string name1("rule1");
-  int ruleset1 = c->add_simple_ruleset(name1, root_name1, "osd",
-                                      "firstn", pg_pool_t::TYPE_REPLICATED);
-  EXPECT_EQ(1, ruleset1);
-
-  vector<unsigned> reweight(n, 0x10000);
-  for (int i=0; i<10000; ++i) {
-    vector<int> out0, out1;
-    c->do_rule(ruleset0, i, out0, 1, reweight);
-    ASSERT_EQ(1u, out0.size());
-    c->do_rule(ruleset1, i, out1, 1, reweight);
-    ASSERT_EQ(1u, out1.size());
-    ASSERT_EQ(out0[0], out1[0]);
-    //cout << i << "\t" << out0 << "\t" << out1 << std::endl;
-  }
-}
-
-TEST(CrushWrapper, straw_same) {
-  // items with the same weight should map about the same as items
-  // with very similar weights.
-  //
-  // give the 0 vector a paired stair pattern, with dup weights.  note
-  // that the original straw flaw does not appear when there are 2 of
-  // the initial weight, but it does when there is just 1.
-  //
-  // give the 1 vector a similar stair pattern, but make the same
-  // steps weights slightly different (no dups).  this works.
-  //
-  // compare the result and verify that the resulting mapping is
-  // almost identical.
-
-  CrushWrapper *c = new CrushWrapper;
-  const int ROOT_TYPE = 1;
-  c->set_type_name(ROOT_TYPE, "root");
-  const int OSD_TYPE = 0;
-  c->set_type_name(OSD_TYPE, "osd");
-
-  int n = 10;
-  int items[n], weights[n];
-  for (int i=0; i <n; ++i) {
-    items[i] = i;
-    weights[i] = 0x10000 * ((i+1)/2 + 1);
-  }
-
-  c->set_max_devices(n);
-
-  string root_name0("root0");
-  int root0;
-  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
-                            ROOT_TYPE, n, items, weights, &root0));
-  EXPECT_EQ(0, c->set_item_name(root0, root_name0));
-
-  string name0("rule0");
-  int ruleset0 = c->add_simple_ruleset(name0, root_name0, "osd",
-                                      "firstn", pg_pool_t::TYPE_REPLICATED);
-  EXPECT_EQ(0, ruleset0);
-
-  for (int i=0; i <n; ++i) {
-    items[i] = i;
-    weights[i] = 0x10000 * ((i+1)/2 + 1) + (i%2)*100;
-  }
-
-  string root_name1("root1");
-  int root1;
-  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
-                            ROOT_TYPE, n, items, weights, &root1));
-  EXPECT_EQ(0, c->set_item_name(root1, root_name1));
-
-  string name1("rule1");
-  int ruleset1 = c->add_simple_ruleset(name1, root_name1, "osd",
-                                      "firstn", pg_pool_t::TYPE_REPLICATED);
-  EXPECT_EQ(1, ruleset1);
-
-  if (0) {
-    crush_bucket_straw *sb0 = reinterpret_cast<crush_bucket_straw*>(c->get_crush_map()->buckets[-1-root0]);
-    crush_bucket_straw *sb1 = reinterpret_cast<crush_bucket_straw*>(c->get_crush_map()->buckets[-1-root1]);
-
-    for (int i=0; i<n; ++i) {
-      cout << i
-          << "\t" << sb0->item_weights[i]
-          << "\t" << sb1->item_weights[i]
-          << "\t"
-          << "\t" << sb0->straws[i]
-          << "\t" << sb1->straws[i]
-          << std::endl;
-    }
-  }
-
-  if (0) {
-    JSONFormatter jf(true);
-    jf.open_object_section("crush");
-    c->dump(&jf);
-    jf.close_section();
-    jf.flush(cout);
-  }
-
-  vector<int> sum0(n, 0), sum1(n, 0);
-  vector<unsigned> reweight(n, 0x10000);
-  int different = 0;
-  int max = 100000;
-  for (int i=0; i<max; ++i) {
-    vector<int> out0, out1;
-    c->do_rule(ruleset0, i, out0, 1, reweight);
-    ASSERT_EQ(1u, out0.size());
-    c->do_rule(ruleset1, i, out1, 1, reweight);
-    ASSERT_EQ(1u, out1.size());
-    sum0[out0[0]]++;
-    sum1[out1[0]]++;
-    if (out0[0] != out1[0])
-      different++;
-  }
-  for (int i=0; i<n; ++i) {
-    cout << i
-        << "\t" << ((double)weights[i] / (double)weights[0])
-        << "\t" << sum0[i] << "\t" << ((double)sum0[i]/(double)sum0[0])
-        << "\t" << sum1[i] << "\t" << ((double)sum1[i]/(double)sum1[0])
-        << std::endl;
-  }
-  double ratio = ((double)different / (double)max);
-  cout << different << " of " << max << " = "
-       << ratio
-       << " different" << std::endl;
-  ASSERT_LT(ratio, .001);
-}
-
 TEST(CrushWrapper, move_bucket) {
   CrushWrapper *c = new CrushWrapper;
 
index 887791472588f08f7063958538e6f4bb7ab6d65d..d22e3f3e594a8770f1fc029f8f7566b80b7bbc2b 100644 (file)
@@ -17,6 +17,7 @@
 #include "global/global_context.h"
 
 #include "crush/CrushWrapper.h"
+#include "osd/osd_types.h"
 
 #include <set>
 
@@ -250,7 +251,165 @@ TEST(CRUSH, indep_out_progressive) {
   delete c;
 }
 
+TEST(CrushWrapper, straw_zero) {
+  // zero weight items should have no effect on placement.
 
+  CrushWrapper *c = new CrushWrapper;
+  const int ROOT_TYPE = 1;
+  c->set_type_name(ROOT_TYPE, "root");
+  const int OSD_TYPE = 0;
+  c->set_type_name(OSD_TYPE, "osd");
+
+  int n = 5;
+  int items[n], weights[n];
+  for (int i=0; i <n; ++i) {
+    items[i] = i;
+    weights[i] = 0x10000 * (n-i-1);
+  }
+
+  c->set_max_devices(n);
+
+  string root_name0("root0");
+  int root0;
+  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
+                            ROOT_TYPE, n, items, weights, &root0));
+  EXPECT_EQ(0, c->set_item_name(root0, root_name0));
+
+  string name0("rule0");
+  int ruleset0 = c->add_simple_ruleset(name0, root_name0, "osd",
+                                      "firstn", pg_pool_t::TYPE_REPLICATED);
+  EXPECT_EQ(0, ruleset0);
+
+  string root_name1("root1");
+  int root1;
+  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
+                            ROOT_TYPE, n-1, items, weights, &root1));
+  EXPECT_EQ(0, c->set_item_name(root1, root_name1));
+
+  string name1("rule1");
+  int ruleset1 = c->add_simple_ruleset(name1, root_name1, "osd",
+                                      "firstn", pg_pool_t::TYPE_REPLICATED);
+  EXPECT_EQ(1, ruleset1);
+
+  vector<unsigned> reweight(n, 0x10000);
+  for (int i=0; i<10000; ++i) {
+    vector<int> out0, out1;
+    c->do_rule(ruleset0, i, out0, 1, reweight);
+    ASSERT_EQ(1u, out0.size());
+    c->do_rule(ruleset1, i, out1, 1, reweight);
+    ASSERT_EQ(1u, out1.size());
+    ASSERT_EQ(out0[0], out1[0]);
+    //cout << i << "\t" << out0 << "\t" << out1 << std::endl;
+  }
+}
+
+TEST(CrushWrapper, straw_same) {
+  // items with the same weight should map about the same as items
+  // with very similar weights.
+  //
+  // give the 0 vector a paired stair pattern, with dup weights.  note
+  // that the original straw flaw does not appear when there are 2 of
+  // the initial weight, but it does when there is just 1.
+  //
+  // give the 1 vector a similar stair pattern, but make the same
+  // steps weights slightly different (no dups).  this works.
+  //
+  // compare the result and verify that the resulting mapping is
+  // almost identical.
+
+  CrushWrapper *c = new CrushWrapper;
+  const int ROOT_TYPE = 1;
+  c->set_type_name(ROOT_TYPE, "root");
+  const int OSD_TYPE = 0;
+  c->set_type_name(OSD_TYPE, "osd");
+
+  int n = 10;
+  int items[n], weights[n];
+  for (int i=0; i <n; ++i) {
+    items[i] = i;
+    weights[i] = 0x10000 * ((i+1)/2 + 1);
+  }
+
+  c->set_max_devices(n);
+
+  string root_name0("root0");
+  int root0;
+  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
+                            ROOT_TYPE, n, items, weights, &root0));
+  EXPECT_EQ(0, c->set_item_name(root0, root_name0));
+
+  string name0("rule0");
+  int ruleset0 = c->add_simple_ruleset(name0, root_name0, "osd",
+                                      "firstn", pg_pool_t::TYPE_REPLICATED);
+  EXPECT_EQ(0, ruleset0);
+
+  for (int i=0; i <n; ++i) {
+    items[i] = i;
+    weights[i] = 0x10000 * ((i+1)/2 + 1) + (i%2)*100;
+  }
+
+  string root_name1("root1");
+  int root1;
+  EXPECT_EQ(0, c->add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_RJENKINS1,
+                            ROOT_TYPE, n, items, weights, &root1));
+  EXPECT_EQ(0, c->set_item_name(root1, root_name1));
+
+  string name1("rule1");
+  int ruleset1 = c->add_simple_ruleset(name1, root_name1, "osd",
+                                      "firstn", pg_pool_t::TYPE_REPLICATED);
+  EXPECT_EQ(1, ruleset1);
+
+  if (0) {
+    crush_bucket_straw *sb0 = reinterpret_cast<crush_bucket_straw*>(c->get_crush_map()->buckets[-1-root0]);
+    crush_bucket_straw *sb1 = reinterpret_cast<crush_bucket_straw*>(c->get_crush_map()->buckets[-1-root1]);
+
+    for (int i=0; i<n; ++i) {
+      cout << i
+          << "\t" << sb0->item_weights[i]
+          << "\t" << sb1->item_weights[i]
+          << "\t"
+          << "\t" << sb0->straws[i]
+          << "\t" << sb1->straws[i]
+          << std::endl;
+    }
+  }
+
+  if (0) {
+    JSONFormatter jf(true);
+    jf.open_object_section("crush");
+    c->dump(&jf);
+    jf.close_section();
+    jf.flush(cout);
+  }
+
+  vector<int> sum0(n, 0), sum1(n, 0);
+  vector<unsigned> reweight(n, 0x10000);
+  int different = 0;
+  int max = 100000;
+  for (int i=0; i<max; ++i) {
+    vector<int> out0, out1;
+    c->do_rule(ruleset0, i, out0, 1, reweight);
+    ASSERT_EQ(1u, out0.size());
+    c->do_rule(ruleset1, i, out1, 1, reweight);
+    ASSERT_EQ(1u, out1.size());
+    sum0[out0[0]]++;
+    sum1[out1[0]]++;
+    if (out0[0] != out1[0])
+      different++;
+  }
+  for (int i=0; i<n; ++i) {
+    cout << i
+        << "\t" << ((double)weights[i] / (double)weights[0])
+        << "\t" << sum0[i] << "\t" << ((double)sum0[i]/(double)sum0[0])
+        << "\t" << sum1[i] << "\t" << ((double)sum1[i]/(double)sum1[0])
+        << std::endl;
+  }
+  double ratio = ((double)different / (double)max);
+  cout << different << " of " << max << " = "
+       << ratio
+       << " different" << std::endl;
+  ASSERT_LT(ratio, .001);
+}
 
 
 int main(int argc, char **argv) {