summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2017-01-04 00:57:52 -0500
committerMichael Cahill <michael.cahill@mongodb.com>2017-01-04 16:57:52 +1100
commit49e48315235a189ed769c43e35e6a73b9a074fa2 (patch)
tree0fe31f891aafc137573d34e18fc0af9b864d1c34
parent5af64580f5be08d2f8900b96a83d29a3ae2cf04a (diff)
downloadmongo-49e48315235a189ed769c43e35e6a73b9a074fa2.tar.gz
WT-3100 test bug: format is weighted to delete, insert, then write operations (#3219)
test/format was weighted to delete, insert, then write operations, which meant that configuring insert=80 might have no effect, if the randomly assigned percentage of delete operations was 95. Rewrite the code that calculates operation percentages to assign operation percentages in a random order, add an explicit read percentage instead of making all non-allocated operations default to reads.
-rw-r--r--test/format/config.c104
-rw-r--r--test/format/config.h18
-rw-r--r--test/format/format.h1
3 files changed, 97 insertions, 26 deletions
diff --git a/test/format/config.c b/test/format/config.c
index cf922b5db04..43447c9ba02 100644
--- a/test/format/config.c
+++ b/test/format/config.c
@@ -44,6 +44,7 @@ static void config_map_compression(const char *, u_int *);
static void config_map_encryption(const char *, u_int *);
static void config_map_file_type(const char *, u_int *);
static void config_map_isolation(const char *, u_int *);
+static void config_pct(void);
static void config_reset(void);
/*
@@ -159,31 +160,19 @@ config_setup(void)
config_encryption();
config_isolation();
config_lrt();
+ config_pct();
/*
- * Periodically, set the delete percentage to 0 so salvage gets run,
- * as long as the delete percentage isn't nailed down.
- * Don't do it on the first run, all our smoke tests would hit it.
- */
- if (!g.replay && g.run_cnt % 10 == 9 && !config_is_perm("delete_pct"))
- config_single("delete_pct=0", 0);
-
- /*
- * If this is an LSM run, set the cache size and crank up the insert
- * percentage.
+ * If this is an LSM run, ensure cache size sanity.
+ * Ensure there is at least 1MB of cache per thread.
*/
- if (DATASOURCE("lsm")) {
- if (!config_is_perm("cache"))
+ if (!config_is_perm("cache")) {
+ if (DATASOURCE("lsm"))
g.c_cache = 30 * g.c_chunk_size;
-
- if (!config_is_perm("insert_pct"))
- g.c_insert_pct = mmrand(NULL, 50, 85);
+ if (g.c_cache < g.c_threads)
+ g.c_cache = g.c_threads;
}
- /* Ensure there is at least 1MB of cache per thread. */
- if (!config_is_perm("cache") && g.c_cache < g.c_threads)
- g.c_cache = g.c_threads;
-
/* Give in-memory configuration a final review. */
config_in_memory_check();
@@ -482,6 +471,83 @@ config_lrt(void)
}
/*
+ * config_pct --
+ * Configure operation percentages.
+ */
+static void
+config_pct(void)
+{
+ static struct {
+ const char *name; /* Operation */
+ uint32_t *vp; /* Value store */
+ u_int order; /* Order of assignment */
+ } list[] = {
+#define CONFIG_DELETE_ENTRY 0
+ { "delete_pct", &g.c_delete_pct, 0 },
+ { "insert_pct", &g.c_insert_pct, 0 },
+ { "read_pct", &g.c_read_pct, 0 },
+ { "write_pct", &g.c_write_pct, 0 },
+ };
+ u_int i, max_order, max_slot, n, pct;
+
+ /*
+ * Walk the list of operations, checking for an illegal configuration
+ * and creating a random order in the list.
+ */
+ pct = 0;
+ for (i = 0; i < WT_ELEMENTS(list); ++i)
+ if (config_is_perm(list[i].name))
+ pct += *list[i].vp;
+ else
+ list[i].order = mmrand(NULL, 0, 1000);
+ if (pct > 100)
+ testutil_die(EINVAL,
+ "operation percentages total to more than 100%%");
+
+ /*
+ * If the delete percentage isn't nailed down, periodically set it to
+ * 0 so salvage gets run. Don't do it on the first run, all our smoke
+ * tests would hit it.
+ */
+ if (!config_is_perm("delete_pct") && !g.replay && g.run_cnt % 10 == 9) {
+ list[CONFIG_DELETE_ENTRY].order = 0;
+ *list[CONFIG_DELETE_ENTRY].vp = 0;
+ }
+
+ /*
+ * Walk the list, allocating random numbers of operations in a random
+ * order.
+ *
+ * If the "order" field is non-zero, we need to create a value for this
+ * operation. Find the largest order field in the array; if one non-zero
+ * order field is found, it's the last entry and gets the remainder of
+ * the operations.
+ */
+ for (pct = 100 - pct;;) {
+ for (i = n =
+ max_order = max_slot = 0; i < WT_ELEMENTS(list); ++i) {
+ if (list[i].order != 0)
+ ++n;
+ if (list[i].order > max_order) {
+ max_order = list[i].order;
+ max_slot = i;
+ }
+ }
+ if (n == 0)
+ break;
+ if (n == 1) {
+ *list[max_slot].vp = pct;
+ break;
+ }
+ *list[max_slot].vp = mmrand(NULL, 0, pct);
+ list[max_slot].order = 0;
+ pct -= *list[max_slot].vp;
+ }
+ testutil_assert(g.c_delete_pct +
+ g.c_insert_pct + g.c_read_pct + g.c_write_pct == 100);
+}
+
+/*
* config_error --
* Display configuration information on error.
*/
diff --git a/test/format/config.h b/test/format/config.h
index e4f7af2e1b2..e3e1e73a786 100644
--- a/test/format/config.h
+++ b/test/format/config.h
@@ -131,7 +131,7 @@ static CONFIG c[] = {
{ "delete_pct",
"percent operations that are deletes",
- 0x0, 0, 45, 90, &g.c_delete_pct, NULL },
+ C_IGNORE, 0, 0, 100, &g.c_delete_pct, NULL },
{ "dictionary",
"if values are dictionary compressed", /* 20% */
@@ -171,7 +171,7 @@ static CONFIG c[] = {
{ "insert_pct",
"percent operations that are inserts",
- 0x0, 0, 45, 90, &g.c_insert_pct, NULL },
+ C_IGNORE, 0, 0, 100, &g.c_insert_pct, NULL },
{ "internal_key_truncation",
"if internal keys are truncated", /* 95% */
@@ -254,6 +254,14 @@ static CONFIG c[] = {
"quiet run (same as -q)",
C_IGNORE|C_BOOL, 0, 0, 0, &g.c_quiet, NULL },
+ { "read_pct",
+ "percent operations that are reads",
+ C_IGNORE, 0, 0, 100, &g.c_read_pct, NULL },
+
+ { "rebalance",
+ "rebalance testing", /* 100% */
+ C_BOOL, 100, 1, 0, &g.c_rebalance, NULL },
+
{ "repeat_data_pct",
"percent duplicate values in row- or var-length column-stores",
0x0, 0, 90, 90, &g.c_repeat_data_pct, NULL },
@@ -270,10 +278,6 @@ static CONFIG c[] = {
"the number of runs",
C_IGNORE, 0, UINT_MAX, UINT_MAX, &g.c_runs, NULL },
- { "rebalance",
- "rebalance testing", /* 100% */
- C_BOOL, 100, 1, 0, &g.c_rebalance, NULL },
-
{ "salvage",
"salvage testing", /* 100% */
C_BOOL, 100, 1, 0, &g.c_salvage, NULL },
@@ -320,7 +324,7 @@ static CONFIG c[] = {
{ "write_pct",
"percent operations that are writes",
- 0x0, 0, 90, 90, &g.c_write_pct, NULL },
+ C_IGNORE, 0, 0, 100, &g.c_write_pct, NULL },
{ NULL, NULL, 0x0, 0, 0, 0, NULL, NULL }
};
diff --git a/test/format/format.h b/test/format/format.h
index c1f4875dbb2..6bb44410acc 100644
--- a/test/format/format.h
+++ b/test/format/format.h
@@ -192,6 +192,7 @@ typedef struct {
uint32_t c_reverse;
uint32_t c_rows;
uint32_t c_runs;
+ uint32_t c_read_pct;
uint32_t c_rebalance;
uint32_t c_salvage;
uint32_t c_split_pct;