public static GeoDistanceSortBuilder randomGeoDistanceSortBuilder() {
    String fieldName = randomAsciiOfLengthBetween(1, 10);
    GeoDistanceSortBuilder result = null;

    int id = randomIntBetween(0, 2);
    switch (id) {
      case 0:
        int count = randomIntBetween(1, 10);
        String[] geohashes = new String[count];
        for (int i = 0; i < count; i++) {
          geohashes[i] = RandomGeoGenerator.randomPoint(random()).geohash();
        }

        result = new GeoDistanceSortBuilder(fieldName, geohashes);
        break;
      case 1:
        GeoPoint pt = RandomGeoGenerator.randomPoint(random());
        result = new GeoDistanceSortBuilder(fieldName, pt.getLat(), pt.getLon());
        break;
      case 2:
        result = new GeoDistanceSortBuilder(fieldName, points(new GeoPoint[0]));
        break;
      default:
        throw new IllegalStateException("one of three geo initialisation strategies must be used");
    }
    if (randomBoolean()) {
      result.geoDistance(geoDistance(result.geoDistance()));
    }
    if (randomBoolean()) {
      result.unit(randomValueOtherThan(result.unit(), () -> randomFrom(DistanceUnit.values())));
    }
    if (randomBoolean()) {
      result.order(randomFrom(SortOrder.values()));
    }
    if (randomBoolean()) {
      result.sortMode(randomValueOtherThan(SortMode.SUM, () -> randomFrom(SortMode.values())));
    }
    if (randomBoolean()) {
      result.setNestedFilter(randomNestedFilter());
    }
    if (randomBoolean()) {
      result.setNestedPath(
          randomValueOtherThan(result.getNestedPath(), () -> randomAsciiOfLengthBetween(1, 10)));
    }
    if (randomBoolean()) {
      result.validation(
          randomValueOtherThan(
              result.validation(), () -> randomFrom(GeoValidationMethod.values())));
    }

    return result;
  }
 public void testSortModeSumIsRejectedInSetter() {
   GeoDistanceSortBuilder builder = new GeoDistanceSortBuilder("testname", -1, -1);
   GeoPoint point = RandomGeoGenerator.randomPoint(random());
   builder.point(point.getLat(), point.getLon());
   try {
     builder.sortMode(SortMode.SUM);
     fail("sort mode sum should not be supported");
   } catch (IllegalArgumentException e) {
     // all good
   }
 }
 private static GeoPoint[] points(GeoPoint[] original) {
   GeoPoint[] result = null;
   while (result == null || Arrays.deepEquals(original, result)) {
     int count = randomIntBetween(1, 10);
     result = new GeoPoint[count];
     for (int i = 0; i < count; i++) {
       result[i] = RandomGeoGenerator.randomPoint(random());
     }
   }
   return result;
 }
 @Override
 protected GeoDistanceSortBuilder mutate(GeoDistanceSortBuilder original) throws IOException {
   GeoDistanceSortBuilder result = new GeoDistanceSortBuilder(original);
   int parameter = randomIntBetween(0, 8);
   switch (parameter) {
     case 0:
       while (Arrays.deepEquals(original.points(), result.points())) {
         GeoPoint pt = RandomGeoGenerator.randomPoint(random());
         result.point(pt.getLat(), pt.getLon());
       }
       break;
     case 1:
       result.points(points(original.points()));
       break;
     case 2:
       result.geoDistance(geoDistance(original.geoDistance()));
       break;
     case 3:
       result.unit(randomValueOtherThan(result.unit(), () -> randomFrom(DistanceUnit.values())));
       break;
     case 4:
       result.order(randomValueOtherThan(original.order(), () -> randomFrom(SortOrder.values())));
       break;
     case 5:
       result.sortMode(
           randomValueOtherThanMany(
               Arrays.asList(SortMode.SUM, result.sortMode())::contains,
               () -> randomFrom(SortMode.values())));
       break;
     case 6:
       result.setNestedFilter(
           randomValueOtherThan(original.getNestedFilter(), () -> randomNestedFilter()));
       break;
     case 7:
       result.setNestedPath(
           randomValueOtherThan(result.getNestedPath(), () -> randomAsciiOfLengthBetween(1, 10)));
       break;
     case 8:
       result.validation(
           randomValueOtherThan(
               result.validation(), () -> randomFrom(GeoValidationMethod.values())));
       break;
   }
   return result;
 }
  @Override
  protected GeoDistanceRangeQueryBuilder doCreateTestQueryBuilder() {
    GeoDistanceRangeQueryBuilder builder;
    GeoPoint randomPoint = RandomGeoGenerator.randomPointIn(random(), -180.0, -89.9, 180.0, 89.9);
    if (randomBoolean()) {
      builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, randomPoint.geohash());
    } else {
      if (randomBoolean()) {
        builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, randomPoint);
      } else {
        builder =
            new GeoDistanceRangeQueryBuilder(
                GEO_POINT_FIELD_NAME, randomPoint.lat(), randomPoint.lon());
      }
    }
    GeoPoint point = builder.point();
    final double maxRadius = GeoUtils.maxRadialDistanceMeters(point.lat(), point.lon());
    final int fromValueMeters = randomInt((int) (maxRadius * 0.5));
    final int toValueMeters = randomIntBetween(fromValueMeters + 1, (int) maxRadius);
    DistanceUnit fromToUnits = randomFrom(DistanceUnit.values());
    final String fromToUnitsStr = fromToUnits.toString();
    final double fromValue =
        DistanceUnit.convert(fromValueMeters, DistanceUnit.DEFAULT, fromToUnits);
    final double toValue = DistanceUnit.convert(toValueMeters, DistanceUnit.DEFAULT, fromToUnits);

    if (randomBoolean()) {
      int branch = randomInt(2);
      fromToUnits = DistanceUnit.DEFAULT;
      switch (branch) {
        case 0:
          builder.from(fromValueMeters);
          break;
        case 1:
          builder.to(toValueMeters);
          break;
        case 2:
          builder.from(fromValueMeters);
          builder.to(toValueMeters);
          break;
      }
    } else {
      int branch = randomInt(2);
      switch (branch) {
        case 0:
          builder.from(fromValue + fromToUnitsStr);
          break;
        case 1:
          builder.to(toValue + fromToUnitsStr);
          break;
        case 2:
          builder.from(fromValue + fromToUnitsStr);
          builder.to(toValue + fromToUnitsStr);
          break;
      }
    }
    if (randomBoolean()) {
      builder.includeLower(randomBoolean());
    }
    if (randomBoolean()) {
      builder.includeUpper(randomBoolean());
    }
    if (randomBoolean()) {
      builder.geoDistance(randomFrom(GeoDistance.values()));
    }
    builder.unit(fromToUnits);
    if (randomBoolean()) {
      builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
    }

    if (randomBoolean()) {
      builder.ignoreUnmapped(randomBoolean());
    }
    return builder;
  }