~ubuntu-branches/ubuntu/raring/ceph/raring

« back to all changes in this revision

Viewing changes to src/test/osd/TestRados.cc

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2012-02-05 10:07:38 UTC
  • mfrom: (1.1.7) (0.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20120205100738-00s0bxx93mamy8tk
Tags: 0.41-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 
2
#include "common/Mutex.h"
 
3
#include "common/Cond.h"
 
4
 
 
5
#include <iostream>
 
6
#include <sstream>
 
7
#include <map>
 
8
#include <numeric>
 
9
#include <string>
 
10
#include <vector>
 
11
#include <stdlib.h>
 
12
#include <unistd.h>
 
13
 
 
14
#include "test/osd/RadosModel.h"
 
15
 
 
16
using namespace std;
 
17
 
 
18
class WeightedTestGenerator : public TestOpGenerator
 
19
{
 
20
public:
 
21
 
 
22
  WeightedTestGenerator(int ops,
 
23
                        int objects,
 
24
                        map<TestOpType, unsigned int> op_weights,
 
25
                        TestOpStat *stats,
 
26
                        int max_seconds) :
 
27
    m_nextop(NULL), m_op(0), m_ops(ops), m_seconds(max_seconds), m_objects(objects), m_stats(stats),
 
28
    m_total_weight(0)
 
29
  {
 
30
    m_start = time(0);
 
31
    for (map<TestOpType, unsigned int>::const_iterator it = op_weights.begin();
 
32
         it != op_weights.end();
 
33
         ++it) {
 
34
      m_total_weight += it->second;
 
35
      m_weight_sums.insert(pair<TestOpType, unsigned int>(it->first,
 
36
                                                          m_total_weight));
 
37
    }
 
38
  }
 
39
 
 
40
  TestOp *next(RadosTestContext &context)
 
41
  {
 
42
    TestOp *retval = NULL;
 
43
 
 
44
    ++m_op;
 
45
    if (m_op <= m_objects) {
 
46
      stringstream oid;
 
47
      oid << m_op;
 
48
      cout << m_op << ": Writing initial " << oid.str() << std::endl;
 
49
      return new WriteOp(&context, oid.str());
 
50
    } else if (m_op >= m_ops) {
 
51
      return NULL;
 
52
    }
 
53
 
 
54
    if (m_nextop) {
 
55
      retval = m_nextop;
 
56
      m_nextop = NULL;
 
57
      return retval;
 
58
    }
 
59
 
 
60
    while (retval == NULL) {
 
61
      unsigned int rand_val = rand() % m_total_weight;
 
62
 
 
63
      time_t now = time(0);
 
64
      if (m_seconds && now - m_start > m_seconds)
 
65
        break;
 
66
 
 
67
      for (map<TestOpType, unsigned int>::const_iterator it = m_weight_sums.begin();
 
68
           it != m_weight_sums.end();
 
69
           ++it) {
 
70
        if (rand_val < it->second) {
 
71
          cout << m_op << ": ";
 
72
          retval = gen_op(context, it->first);
 
73
          break;
 
74
        }
 
75
      }
 
76
    }
 
77
    return retval;
 
78
  }
 
79
 
 
80
private:
 
81
 
 
82
  TestOp *gen_op(RadosTestContext &context, TestOpType type)
 
83
  {
 
84
    string oid;
 
85
    switch (type) {
 
86
    case TEST_OP_READ:
 
87
      oid = *(rand_choose(context.oid_not_in_use));
 
88
      cout << "Reading " << oid << std::endl;
 
89
      return new ReadOp(&context, oid, m_stats);
 
90
 
 
91
    case TEST_OP_WRITE:
 
92
      oid = *(rand_choose(context.oid_not_in_use));
 
93
      cout << "Writing " << oid << " current snap is "
 
94
           << context.current_snap << std::endl;
 
95
      return new WriteOp(&context, oid, m_stats);
 
96
 
 
97
    case TEST_OP_DELETE:
 
98
      oid = *(rand_choose(context.oid_not_in_use));
 
99
      cout << "Deleting " << oid << " current snap is "
 
100
           << context.current_snap << std::endl;
 
101
      return new DeleteOp(&context, oid, m_stats);
 
102
 
 
103
    case TEST_OP_SNAP_CREATE:
 
104
      cout << "Snapping" << std::endl;
 
105
      return new SnapCreateOp(&context, m_stats);
 
106
 
 
107
    case TEST_OP_SNAP_REMOVE:
 
108
      if (context.snaps.empty()) {
 
109
        return NULL;
 
110
      } else {
 
111
        int snap = rand_choose(context.snaps)->first;
 
112
        cout << "RemovingSnap " << snap << std::endl;
 
113
        return new SnapRemoveOp(&context, snap, m_stats);
 
114
      }
 
115
 
 
116
    case TEST_OP_ROLLBACK:
 
117
      if (context.snaps.empty()) {
 
118
        return NULL;
 
119
      } else {
 
120
        int snap = rand_choose(context.snaps)->first;
 
121
        string oid = *(rand_choose(context.oid_not_in_use));
 
122
        cout << "RollingBack " << oid << " to " << snap << std::endl;
 
123
        m_nextop = new ReadOp(&context, oid, m_stats);
 
124
        return new RollbackOp(&context, oid, snap);
 
125
      }
 
126
 
 
127
    default:
 
128
      cerr << "Invalid op type " << type << std::endl;
 
129
      assert(0);
 
130
    }
 
131
  }
 
132
 
 
133
  TestOp *m_nextop;
 
134
  int m_op;
 
135
  int m_ops;
 
136
  int m_seconds;
 
137
  int m_objects;
 
138
  time_t m_start;
 
139
  TestOpStat *m_stats;
 
140
  map<TestOpType, unsigned int> m_weight_sums;
 
141
  unsigned int m_total_weight;
 
142
};
 
143
 
 
144
int main(int argc, char **argv)
 
145
{
 
146
  int ops = 1000;
 
147
  int objects = 50;
 
148
  int max_in_flight = 16;
 
149
  int64_t size = 4000000; // 4 MB
 
150
  int64_t min_stride_size = -1, max_stride_size = -1;
 
151
  int max_seconds = 0;
 
152
 
 
153
  struct {
 
154
    TestOpType op;
 
155
    const char *name;
 
156
  } op_types[] = {
 
157
    { TEST_OP_READ, "read" },
 
158
    { TEST_OP_WRITE, "write" },
 
159
    { TEST_OP_DELETE, "delete" },
 
160
    { TEST_OP_SNAP_CREATE, "snap_create" },
 
161
    { TEST_OP_SNAP_REMOVE, "snap_remove" },
 
162
    { TEST_OP_ROLLBACK, "rollback" },
 
163
    { TEST_OP_READ /* grr */, NULL },
 
164
  };
 
165
 
 
166
  map<TestOpType, unsigned int> op_weights;
 
167
 
 
168
  for (int i = 1; i < argc; ++i) {
 
169
    if (strcmp(argv[i], "--max-ops") == 0)
 
170
      ops = atoi(argv[++i]);
 
171
    else if (strcmp(argv[i], "--max-seconds") == 0)
 
172
      max_seconds = atoi(argv[++i]);
 
173
    else if (strcmp(argv[i], "--objects") == 0)
 
174
      objects = atoi(argv[++i]);
 
175
    else if (strcmp(argv[i], "--max-in-flight") == 0)
 
176
      max_in_flight = atoi(argv[++i]);
 
177
    else if (strcmp(argv[i], "--size") == 0)
 
178
      size = atoi(argv[++i]);
 
179
    else if (strcmp(argv[i], "--min-stride-size") == 0)
 
180
      min_stride_size = atoi(argv[++i]);
 
181
    else if (strcmp(argv[i], "--max-stride-size") == 0)
 
182
      max_stride_size = atoi(argv[++i]);
 
183
    else if (strcmp(argv[i], "--op") == 0) {
 
184
      i++;
 
185
      int j;
 
186
      for (j = 0; op_types[j].name; ++j) {
 
187
        if (strcmp(op_types[j].name, argv[i]) == 0) {
 
188
          break;
 
189
        }
 
190
      }
 
191
      if (!op_types[j].name) {
 
192
        cerr << "unknown op " << argv[i] << std::endl;
 
193
        exit(1);
 
194
      }
 
195
      int weight = atoi(argv[++i]);
 
196
      if (weight < 0) {
 
197
        cerr << "Weights must be nonnegative." << std::endl;
 
198
        return 1;
 
199
      }
 
200
      cout << "adding op weight " << op_types[j].name << " -> " << weight << std::endl;
 
201
      op_weights.insert(pair<TestOpType, unsigned int>(op_types[j].op, weight));
 
202
    } else {
 
203
      cerr << "unknown arg " << argv[i] << std::endl;
 
204
      //usage();
 
205
      exit(1);
 
206
    }
 
207
  }
 
208
 
 
209
  if (min_stride_size < 0)
 
210
    min_stride_size = size / 10;
 
211
  if (max_stride_size < 0)
 
212
    max_stride_size = size / 5;
 
213
 
 
214
  cout << "Configuration:" << std::endl
 
215
       << "\tNumber of operations: " << ops << std::endl
 
216
       << "\tNumber of objects: " << objects << std::endl
 
217
       << "\tMax in flight operations: " << max_in_flight << std::endl
 
218
       << "\tObject size (in bytes): " << size << std::endl
 
219
       << "\tWrite stride min: " << min_stride_size << std::endl
 
220
       << "\tWrite stride max: " << max_stride_size << std::endl;
 
221
 
 
222
  if (min_stride_size > max_stride_size) {
 
223
    cerr << "Error: min_stride_size cannot be more than max_stride_size"
 
224
         << std::endl;
 
225
    return 1;
 
226
  }
 
227
 
 
228
  if (min_stride_size > size || max_stride_size > size) {
 
229
    cerr << "Error: min_stride_size and max_stride_size must be "
 
230
         << "smaller than object size" << std::endl;
 
231
    return 1;
 
232
  }
 
233
 
 
234
  if (max_in_flight > objects) {
 
235
    cerr << "Error: max_in_flight must be less than the number of objects"
 
236
         << std::endl;
 
237
    return 1;
 
238
  }
 
239
 
 
240
  char *id = getenv("CEPH_CLIENT_ID");
 
241
  string pool_name = "data";
 
242
  VarLenGenerator cont_gen(size, min_stride_size, max_stride_size);
 
243
  RadosTestContext context(pool_name, max_in_flight, cont_gen, id);
 
244
 
 
245
  TestOpStat stats;
 
246
  WeightedTestGenerator gen = WeightedTestGenerator(ops, objects,
 
247
                                                    op_weights, &stats, max_seconds);
 
248
  context.loop(&gen);
 
249
 
 
250
  context.shutdown();
 
251
  cerr << context.errors << " errors." << std::endl;
 
252
  cerr << stats << std::endl;
 
253
  return 0;
 
254
}