text: /**
   * This file tests the top-chunk optimization logic in splitChunk command.
   * Whenever a chunk is split, the shouldMigrate field should be set if the extreme chunk
   * has only a single document, where extreme chunk is defined as the chunk containing
   * either the upper or lower bound of the entire shard key space.
   */
  
  var st = new ShardingTest({ shards: 1 });
  st.stopBalancer();
  
  var testDB = st.s.getDB('test');
  testDB.adminCommand({ enableSharding: 'test' });
  
  var callSplit = function(db, minKey, maxKey, splitPoints) {
      var res = st.s.adminCommand({getShardVersion: "test.user"});
      assert.commandWorked(res);
      var shardVersion = [res.version, res.versionEpoch];
      return db.runCommand({
          splitChunk: 'test.user',
          from: 'shard0000',
          min: minKey,
          max: maxKey,
          keyPattern: { x: 1 },
          splitKeys: splitPoints,
          shardVersion: shardVersion,
      });
  };
  
  var tests = [
  //
  // Lower extreme chunk tests.
  //
  
  // All chunks have 1 doc.
  //
  // Expected doc counts for new chunks:
  // [ MinKey, -2 ): 1
  // [ -2, -1 ): 1
  // [ -1, 0): 1
  //
  function(db) {
      var res = callSplit(db, { x: MinKey }, { x: 0 }, [{ x: -2 }, { x: -1 }]);
      assert.commandWorked(res);
      assert.neq(res.shouldMigrate, null, tojson(res));
      assert(bsonWoCompare(res.shouldMigrate.min, { x: MinKey }) == 0, tojson(res.shouldMigrate.min));
      assert(bsonWoCompare(res.shouldMigrate.max, { x: -2 }) == 0, tojson(res.shouldMigrate.max));
  },
  
  // One chunk has single doc, extreme doesn't.
  //
  // Expected doc counts for new chunks:
  // [ MinKey, -1 ): 2
  // [ -1, 0): 1
  //
  function(db) {
      var res = callSplit(db, { x: MinKey }, { x: 0 }, [{ x: -1 }]);
      assert.commandWorked(res);
      assert.eq(res.shouldMigrate, null, tojson(res));
  },
  
  // Only extreme has single doc.
  //
  // Expected doc counts for new chunks:
  // [ MinKey, -2 ): 1
  // [ -2, 0): 2
  //
  function(db) {
      var res = callSplit(db, { x: MinKey }, { x: 0 }, [{ x: -2 }]);
      assert.commandWorked(res);
      assert.neq(res.shouldMigrate, null, tojson(res));
      assert(bsonWoCompare(res.shouldMigrate.min, { x: MinKey }) == 0, tojson(res.shouldMigrate.min));
      assert(bsonWoCompare(res.shouldMigrate.max, { x: -2 }) == 0, tojson(res.shouldMigrate.max));
  },
  
  //
  // Upper extreme chunk tests.
  //
  
  // All chunks have 1 doc.
  //
  // Expected doc counts for new chunks:
  // [ 0, 1 ): 1
  // [ 1, 2 ): 1
  // [ 2, MaxKey): 1
  //
  function(db) {
      var res = callSplit(db, { x: 0 }, { x: MaxKey }, [{ x: 1 }, { x: 2 }]);
      assert.commandWorked(res);
      assert.neq(res.shouldMigrate, null, tojson(res));
      assert(bsonWoCompare(res.shouldMigrate.min, { x: 2 }) == 0, tojson(res.shouldMigrate.min));
      assert(bsonWoCompare(res.shouldMigrate.max, { x: MaxKey }) == 0, tojson(res.shouldMigrate.max));
  },
  
  // One chunk has single doc, extreme doesn't.
  //
  // Expected doc counts for new chunks:
  // [ 0, 1 ): 1
  // [ 1, MaxKey): 2
  //
  function(db) {
      var res = callSplit(db, { x: 0 }, { x: MaxKey }, [{ x: 1 }]);
      assert.commandWorked(res);
      assert.eq(res.shouldMigrate, null, tojson(res));
  },
  
  // Only extreme has single doc.
  //
  // Expected doc counts for new chunks:
  // [ 0, 2 ): 2
  // [ 2, MaxKey): 1
  //
  function(db) {
      var res = callSplit(db, { x: 0 }, { x: MaxKey }, [{ x: 2 }]);
      assert.commandWorked(res);
      assert.neq(res.shouldMigrate, null, tojson(res));
      assert(bsonWoCompare(res.shouldMigrate.min, { x: 2 }) == 0, tojson(res.shouldMigrate.min));
      assert(bsonWoCompare(res.shouldMigrate.max, { x: MaxKey }) == 0, tojson(res.shouldMigrate.max));
  },
  ];
  
  tests.forEach(function(test) {
      // setup
      testDB.adminCommand({ shardCollection: 'test.user', key: { x: 1 }});
      testDB.adminCommand({ split: 'test.user', middle: { x: 0 }});
  
      for (var x = -3; x < 3; x++) {
          testDB.user.insert({ x: x });
      }
  
      // run test
      test(st.d0.getDB('admin'));
  
      // teardown
      testDB.user.drop();
  });
  
  st.stop();
  
  