protected void test()

in solr/test-framework/src/java/org/apache/solr/cloud/AbstractBasicDistributedZkTestBase.java [183:756]


  protected void test() throws Exception {
    // setLoggingLevel(null);

    ZkStateReader zkStateReader = ZkStateReader.from(cloudClient);
    // make sure we have leaders for each shard
    for (int j = 1; j < sliceCount; j++) {
      zkStateReader.getLeaderRetry(DEFAULT_COLLECTION, "shard" + j, 10000);
    } // make sure we again have leaders for each shard

    waitForRecoveriesToFinish(false);

    handle.clear();
    handle.put("timestamp", SKIPVAL);

    del("*:*");
    queryAndCompareShards(params("q", "*:*", "distrib", "false", "sanity_check", "is_empty"));

    // ask every individual replica of every shard to update+commit the same doc id
    // with an incrementing counter on each update+commit
    int foo_i_counter = 0;
    for (SolrClient client : clients) {
      foo_i_counter++;
      indexDoc(
          client,
          params("commit", "true"), // SOLR-4923
          sdoc(id, 1, i1, 100, tlong, 100, "foo_i", foo_i_counter));
      // after every update+commit, check all the shards consistency
      queryAndCompareShards(
          params("q", "id:1", "distrib", "false", "sanity_check", "non_distrib_id_1_lookup"));
      queryAndCompareShards(
          params(
              "q", "id:1",
              "sanity_check", "distrib_id_1_lookup"));
    }

    indexr(
        id,
        1,
        i1,
        100,
        tlong,
        100,
        t1,
        "now is the time for all good men",
        "foo_f",
        1.414f,
        "foo_b",
        "true",
        "foo_d",
        1.414d,
        tsort,
        "now is the time for all good men");
    indexr(
        id,
        2,
        i1,
        50,
        tlong,
        50,
        t1,
        "to come to the aid of their country.",
        tsort,
        "to come to the aid of their country.");
    indexr(id, 3, i1, 2, tlong, 2, t1, "how now brown cow", tsort, "how now brown cow");
    indexr(
        id,
        4,
        i1,
        -100,
        tlong,
        101,
        t1,
        "the quick fox jumped over the lazy dog",
        tsort,
        "the quick fox jumped over the lazy dog");
    indexr(
        id,
        5,
        i1,
        500,
        tlong,
        500,
        t1,
        "the quick fox jumped way over the lazy dog",
        tsort,
        "the quick fox jumped over the lazy dog");
    indexr(
        id,
        6,
        i1,
        -600,
        tlong,
        600,
        t1,
        "humpty dumpy sat on a wall",
        tsort,
        "the quick fox jumped over the lazy dog");
    indexr(
        id,
        7,
        i1,
        123,
        tlong,
        123,
        t1,
        "humpty dumpy had a great fall",
        tsort,
        "the quick fox jumped over the lazy dog");
    indexr(
        id,
        8,
        i1,
        876,
        tlong,
        876,
        t1,
        "all the kings horses and all the kings men",
        tsort,
        "all the kings horses and all the kings men");
    indexr(
        id,
        9,
        i1,
        7,
        tlong,
        7,
        t1,
        "couldn't put humpty together again",
        tsort,
        "the quick fox jumped over the lazy dog");
    indexr(id, 10, i1, 4321, tlong, 4321, t1, "this too shall pass", tsort, "this too shall pass");
    indexr(
        id,
        11,
        i1,
        -987,
        tlong,
        987,
        t1,
        "An eye for eye only ends up making the whole world blind.",
        tsort,
        "An eye for eye only ends up making the whole world blind.");
    indexr(
        id,
        12,
        i1,
        379,
        tlong,
        379,
        t1,
        "Great works are performed, not by strength, but by perseverance.",
        tsort,
        "Great works are performed, not by strength, but by perseverance.");
    indexr(
        id,
        13,
        i1,
        232,
        tlong,
        232,
        t1,
        "no eggs on wall, lesson learned",
        oddField,
        "odd man out",
        tsort,
        "no eggs on wall, lesson learned");

    indexr(
        id,
        14,
        "SubjectTerms_mfacet",
        new String[] {"mathematical models", "mathematical analysis"});
    indexr(id, 15, "SubjectTerms_mfacet", new String[] {"test 1", "test 2", "test3"});
    indexr(id, 16, "SubjectTerms_mfacet", new String[] {"test 1", "test 2", "test3"});
    String[] vals = new String[100];
    for (int i = 0; i < 100; i++) {
      vals[i] = "test " + i;
    }
    indexr(id, 17, "SubjectTerms_mfacet", vals);

    for (int i = 100; i < 150; i++) {
      indexr(id, i);
    }

    commit();

    testTokenizedGrouping();
    testSortableTextFaceting();
    testSortableTextSorting();
    testSortableTextGrouping();

    queryAndCompareShards(
        params(
            "q", "*:*",
            "sort", "id desc",
            "distrib", "false",
            "sanity_check", "is_empty"));

    // random value sort
    for (String f : fieldNames) {
      query(false, new String[] {"q", "*:*", "sort", f + " desc"});
      query(false, new String[] {"q", "*:*", "sort", f + " asc"});
    }

    // these queries should be exactly ordered and scores should exactly match
    query(false, new String[] {"q", "*:*", "sort", i1 + " desc"});
    query(false, new String[] {"q", "*:*", "sort", i1 + " asc"});
    query(false, new String[] {"q", "*:*", "sort", i1 + " desc", "fl", "*,score"});
    query(false, new String[] {"q", "*:*", "sort", "n_tl1 asc", "fl", "*,score"});
    query(false, new String[] {"q", "*:*", "sort", "n_tl1 desc"});
    handle.put("maxScore", SKIPVAL);
    query(
        false,
        new String[] {"q", "{!func}" + i1}); // does not expect maxScore. So if it comes ,ignore it.
    // JavaBinCodec.writeSolrDocumentList()
    // is agnostic of request params.
    handle.remove("maxScore");
    query(
        false,
        new String[] {
          "q", "{!func}" + i1, "fl", "*,score"
        }); // even scores should match exactly here

    handle.put("highlighting", UNORDERED);
    handle.put("response", UNORDERED);

    handle.put("maxScore", SKIPVAL);
    query(false, new String[] {"q", "quick"});
    query(false, new String[] {"q", "all", "fl", "id", "start", "0"});
    query(
        false,
        new String[] {"q", "all", "fl", "foofoofoo", "start", "0"}); // no fields in returned docs
    query(false, new String[] {"q", "all", "fl", "id", "start", "100"});

    handle.put("score", SKIPVAL);
    query(false, new String[] {"q", "quick", "fl", "*,score"});
    query(false, new String[] {"q", "all", "fl", "*,score", "start", "1"});
    query(false, new String[] {"q", "all", "fl", "*,score", "start", "100"});

    query(
        false,
        new String[] {
          "q", "now their fox sat had put", "fl", "*,score", "hl", "true", "hl.fl", t1
        });

    query(
        false,
        new String[] {
          "q", "now their fox sat had put", "fl", "foofoofoo", "hl", "true", "hl.fl", t1
        });

    query(false, new String[] {"q", "matchesnothing", "fl", "*,score"});

    query(false, new Object[] {"q", "*:*", "rows", 100, "facet", "true", "facet.field", t1});
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.field",
          t1,
          "facet.limit",
          -1,
          "facet.sort",
          "count"
        });
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.field",
          t1,
          "facet.limit",
          -1,
          "facet.sort",
          "count",
          "facet.mincount",
          2
        });
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.field",
          t1,
          "facet.limit",
          -1,
          "facet.sort",
          "index"
        });
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.field",
          t1,
          "facet.limit",
          -1,
          "facet.sort",
          "index",
          "facet.mincount",
          2
        });
    query(
        false,
        new Object[] {
          "q", "*:*", "rows", 100, "facet", "true", "facet.field", t1, "facet.limit", 1
        });
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.query",
          "quick",
          "facet.query",
          "all",
          "facet.query",
          "*:*"
        });
    query(
        false,
        new Object[] {
          "q", "*:*", "rows", 100, "facet", "true", "facet.field", t1, "facet.offset", 1
        });
    query(
        false,
        new Object[] {
          "q", "*:*", "rows", 100, "facet", "true", "facet.field", t1, "facet.mincount", 2
        });

    // test faceting multiple things at once
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.query",
          "quick",
          "facet.query",
          "all",
          "facet.query",
          "*:*",
          "facet.field",
          t1
        });

    // test filter tagging, facet exclusion, and naming (multi-select facet support)
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          100,
          "facet",
          "true",
          "facet.query",
          "{!key=myquick}quick",
          "facet.query",
          "{!key=myall ex=a}all",
          "facet.query",
          "*:*",
          "facet.field",
          "{!key=mykey ex=a}" + t1,
          "facet.field",
          "{!key=other ex=b}" + t1,
          "facet.field",
          "{!key=again ex=a,b}" + t1,
          "facet.field",
          t1,
          "fq",
          "{!tag=a}id_i1:[1 TO 7]",
          "fq",
          "{!tag=b}id_i1:[3 TO 9]"
        });
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "facet",
          "true",
          "facet.field",
          "{!ex=t1}SubjectTerms_mfacet",
          "fq",
          "{!tag=t1}SubjectTerms_mfacet:(test 1)",
          "facet.limit",
          "10",
          "facet.mincount",
          "1"
        });

    // test field that is valid in schema but missing in all shards
    query(
        false,
        new Object[] {
          "q", "*:*", "rows", 100, "facet", "true", "facet.field", missingField, "facet.mincount", 2
        });
    // test field that is valid in schema and missing in some shards
    query(
        false,
        new Object[] {
          "q", "*:*", "rows", 100, "facet", "true", "facet.field", oddField, "facet.mincount", 2
        });

    query(
        false, new Object[] {"q", "*:*", "sort", i1 + " desc", "stats", "true", "stats.field", i1});

    /* TODO: the failure may come back in "exception"
    try {
      // test error produced for field that is invalid for schema
      query("q","*:*", "rows",100, "facet","true", "facet.field",invalidField, "facet.mincount",2);
      TestCase.fail("SolrServerException expected for invalid field that is not in schema");
    } catch (SolrServerException ex) {
      // expected
    }
    */

    // Try to get better coverage for refinement queries by turning off over requesting.
    // This makes it much more likely that we may not get the top facet values and hence
    // we turn of that checking.
    handle.put("facet_fields", SKIPVAL);
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          0,
          "facet",
          "true",
          "facet.field",
          t1,
          "facet.limit",
          5,
          "facet.shard.limit",
          5
        });
    // check a complex key name
    query(
        false,
        new Object[] {
          "q",
          "*:*",
          "rows",
          0,
          "facet",
          "true",
          "facet.field",
          "{!key='a b/c \\' \\} foo'}" + t1,
          "facet.limit",
          5,
          "facet.shard.limit",
          5
        });
    handle.remove("facet_fields");

    // index the same document to two servers and make sure things
    // don't blow up.
    if (clients.size() >= 2) {
      index(id, 100, i1, 107, t1, "oh no, a duplicate!");
      for (int i = 0; i < clients.size(); i++) {
        index_specific(i, id, 100, i1, 107, t1, "oh no, a duplicate!");
      }
      commit();
      query(false, new Object[] {"q", "duplicate", "hl", "true", "hl.fl", t1});
      query(false, new Object[] {"q", "fox duplicate horses", "hl", "true", "hl.fl", t1});
      query(false, new Object[] {"q", "*:*", "rows", 100});
    }

    // test debugging
    handle.put("explain", SKIPVAL);
    handle.put("debug", UNORDERED);
    handle.put("time", SKIPVAL);
    handle.put("track", SKIP);
    query(
        false,
        new Object[] {
          "q", "now their fox sat had put", "fl", "*,score", CommonParams.DEBUG_QUERY, "true"
        });
    query(false, new Object[] {"q", "id_i1:[1 TO 5]", CommonParams.DEBUG_QUERY, "true"});
    query(false, new Object[] {"q", "id_i1:[1 TO 5]", CommonParams.DEBUG, CommonParams.TIMING});
    query(false, new Object[] {"q", "id_i1:[1 TO 5]", CommonParams.DEBUG, CommonParams.RESULTS});
    query(false, new Object[] {"q", "id_i1:[1 TO 5]", CommonParams.DEBUG, CommonParams.QUERY});

    // try add commitWithin
    long before = cloudClient.query(new SolrQuery("*:*")).getResults().getNumFound();
    for (SolrClient client : clients) {
      assertEquals(
          "unexpected pre-commitWithin document count on node: "
              + ((HttpSolrClient) client).getBaseURL(),
          before,
          client.query(new SolrQuery("*:*")).getResults().getNumFound());
    }

    ModifiableSolrParams params = new ModifiableSolrParams();
    params.set("commitWithin", 10);
    add(cloudClient, params, List.of(getDoc("id", 300), getDoc("id", 301)));

    newSearcherHook.waitForSearcher(DEFAULT_COLLECTION, 2, 20000, false);

    ClusterState clusterState = getCommonCloudSolrClient().getClusterState();
    DocCollection dColl = clusterState.getCollection(DEFAULT_COLLECTION);

    assertSliceCounts("should have found 2 docs, 300 and 301", before + 2, dColl);

    // try deleteById commitWithin
    UpdateRequest deleteByIdReq = new UpdateRequest();
    deleteByIdReq.deleteById("300");
    deleteByIdReq.setCommitWithin(10);
    deleteByIdReq.process(cloudClient);

    newSearcherHook.waitForSearcher(DEFAULT_COLLECTION, 2, 20000, false);

    assertSliceCounts("deleteById commitWithin did not work", before + 1, dColl);

    // try deleteByQuery commitWithin
    UpdateRequest deleteByQueryReq = new UpdateRequest();
    deleteByQueryReq.deleteByQuery("id:301");
    deleteByQueryReq.setCommitWithin(10);
    deleteByQueryReq.process(cloudClient);

    newSearcherHook.waitForSearcher(DEFAULT_COLLECTION, 2, 20000, false);

    assertSliceCounts("deleteByQuery commitWithin did not work", before, dColl);

    // TODO: This test currently fails because debug info is obtained only
    // on shards with matches.
    // query("q","matchesnothing","fl","*,score", "debugQuery", "true");

    // would be better if these where all separate tests - but much, much
    // slower
    doOptimisticLockingAndUpdating();
    testShardParamVariations();
    testMultipleCollections();
    testANewCollectionInOneInstance();
    testSearchByCollectionName();
    testUpdateByCollectionName();
    testANewCollectionInOneInstanceWithManualShardAssignement();
    testNumberOfCommitsWithCommitAfterAdd();

    testUpdateProcessorsRunOnlyOnce("distrib-dup-test-chain-explicit");
    testUpdateProcessorsRunOnlyOnce("distrib-dup-test-chain-implicit");

    testStopAndStartCoresInOneInstance();
  }