/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ package org.opensearch.cluster.coordination; import org.opensearch.Version; import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.node.DiscoveryNode; import org.opensearch.common.util.set.Sets; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.test.EqualsHashCodeTestUtils; import org.opensearch.test.EqualsHashCodeTestUtils.CopyFunction; import java.util.Optional; public class MessagesTests extends OpenSearchTestCase { private DiscoveryNode createNode(String id) { return new DiscoveryNode(id, buildNewFakeTransportAddress(), Version.CURRENT); } public void testJoinEqualsHashCodeSerialization() { Join initialJoin = new Join( createNode(randomAlphaOfLength(10)), createNode(randomAlphaOfLength(10)), randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong() ); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialJoin, (CopyFunction) join -> copyWriteable(join, writableRegistry(), Join::new), join -> { switch (randomInt(4)) { case 0: // change sourceNode return new Join( createNode(randomAlphaOfLength(20)), join.getTargetNode(), join.getTerm(), join.getLastAcceptedTerm(), join.getLastAcceptedVersion() ); case 1: // change targetNode return new Join( join.getSourceNode(), createNode(randomAlphaOfLength(20)), join.getTerm(), join.getLastAcceptedTerm(), join.getLastAcceptedVersion() ); case 2: // change term return new Join( join.getSourceNode(), join.getTargetNode(), randomValueOtherThan(join.getTerm(), OpenSearchTestCase::randomNonNegativeLong), join.getLastAcceptedTerm(), join.getLastAcceptedVersion() ); case 3: // change last accepted term return new Join( join.getSourceNode(), join.getTargetNode(), join.getTerm(), randomValueOtherThan(join.getLastAcceptedTerm(), OpenSearchTestCase::randomNonNegativeLong), join.getLastAcceptedVersion() ); case 4: // change version return new Join( join.getSourceNode(), join.getTargetNode(), join.getTerm(), join.getLastAcceptedTerm(), randomValueOtherThan(join.getLastAcceptedVersion(), OpenSearchTestCase::randomNonNegativeLong) ); default: throw new AssertionError(); } } ); } public void testPublishRequestEqualsHashCode() { PublishRequest initialPublishRequest = new PublishRequest(randomClusterState()); EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialPublishRequest, publishRequest -> new PublishRequest(publishRequest.getAcceptedState()), in -> new PublishRequest(randomClusterState()) ); } public void testPublishResponseEqualsHashCodeSerialization() { PublishResponse initialPublishResponse = new PublishResponse(randomNonNegativeLong(), randomNonNegativeLong()); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialPublishResponse, (CopyFunction) publishResponse -> copyWriteable(publishResponse, writableRegistry(), PublishResponse::new), publishResponse -> { switch (randomInt(1)) { case 0: // change term return new PublishResponse( randomValueOtherThan(publishResponse.getTerm(), OpenSearchTestCase::randomNonNegativeLong), publishResponse.getVersion() ); case 1: // change version return new PublishResponse( publishResponse.getTerm(), randomValueOtherThan(publishResponse.getVersion(), OpenSearchTestCase::randomNonNegativeLong) ); default: throw new AssertionError(); } } ); } public void testPublishWithJoinResponseEqualsHashCodeSerialization() { PublishResponse initialPublishResponse = new PublishResponse(randomNonNegativeLong(), randomNonNegativeLong()); Join initialJoin = new Join( createNode(randomAlphaOfLength(10)), createNode(randomAlphaOfLength(10)), randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong() ); PublishWithJoinResponse initialPublishWithJoinResponse = new PublishWithJoinResponse( initialPublishResponse, randomBoolean() ? Optional.empty() : Optional.of(initialJoin) ); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialPublishWithJoinResponse, (CopyFunction) publishWithJoinResponse -> copyWriteable( publishWithJoinResponse, writableRegistry(), PublishWithJoinResponse::new ), publishWithJoinResponse -> { switch (randomInt(1)) { case 0: // change publish response return new PublishWithJoinResponse( new PublishResponse(randomNonNegativeLong(), randomNonNegativeLong()), publishWithJoinResponse.getJoin() ); case 1: // change optional join Join newJoin = new Join( createNode(randomAlphaOfLength(10)), createNode(randomAlphaOfLength(10)), randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong() ); return new PublishWithJoinResponse( publishWithJoinResponse.getPublishResponse(), publishWithJoinResponse.getJoin().isPresent() && randomBoolean() ? Optional.empty() : Optional.of(newJoin) ); default: throw new AssertionError(); } } ); } public void testStartJoinRequestEqualsHashCodeSerialization() { StartJoinRequest initialStartJoinRequest = new StartJoinRequest(createNode(randomAlphaOfLength(10)), randomNonNegativeLong()); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialStartJoinRequest, (CopyFunction) startJoinRequest -> copyWriteable(startJoinRequest, writableRegistry(), StartJoinRequest::new), startJoinRequest -> { switch (randomInt(1)) { case 0: // change sourceNode return new StartJoinRequest(createNode(randomAlphaOfLength(20)), startJoinRequest.getTerm()); case 1: // change term return new StartJoinRequest( startJoinRequest.getSourceNode(), randomValueOtherThan(startJoinRequest.getTerm(), OpenSearchTestCase::randomNonNegativeLong) ); default: throw new AssertionError(); } } ); } public void testApplyCommitEqualsHashCodeSerialization() { ApplyCommitRequest initialApplyCommit = new ApplyCommitRequest( createNode(randomAlphaOfLength(10)), randomNonNegativeLong(), randomNonNegativeLong() ); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialApplyCommit, (CopyFunction) applyCommit -> copyWriteable(applyCommit, writableRegistry(), ApplyCommitRequest::new), applyCommit -> { switch (randomInt(2)) { case 0: // change sourceNode return new ApplyCommitRequest(createNode(randomAlphaOfLength(20)), applyCommit.getTerm(), applyCommit.getVersion()); case 1: // change term return new ApplyCommitRequest( applyCommit.getSourceNode(), randomValueOtherThan(applyCommit.getTerm(), OpenSearchTestCase::randomNonNegativeLong), applyCommit.getVersion() ); case 2: // change version return new ApplyCommitRequest( applyCommit.getSourceNode(), applyCommit.getTerm(), randomValueOtherThan(applyCommit.getVersion(), OpenSearchTestCase::randomNonNegativeLong) ); default: throw new AssertionError(); } } ); } public void testJoinRequestEqualsHashCodeSerialization() { Join initialJoin = new Join( createNode(randomAlphaOfLength(10)), createNode(randomAlphaOfLength(10)), randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong() ); JoinRequest initialJoinRequest = new JoinRequest( initialJoin.getSourceNode(), randomNonNegativeLong(), randomBoolean() ? Optional.empty() : Optional.of(initialJoin) ); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialJoinRequest, (CopyFunction) joinRequest -> copyWriteable(joinRequest, writableRegistry(), JoinRequest::new), joinRequest -> { if (randomBoolean() && joinRequest.getOptionalJoin().isPresent() == false) { return new JoinRequest( createNode(randomAlphaOfLength(10)), joinRequest.getMinimumTerm(), joinRequest.getOptionalJoin() ); } else if (randomBoolean()) { return new JoinRequest( joinRequest.getSourceNode(), randomValueOtherThan(joinRequest.getMinimumTerm(), OpenSearchTestCase::randomNonNegativeLong), joinRequest.getOptionalJoin() ); } else { // change OptionalJoin final Optional newOptionalJoin; if (joinRequest.getOptionalJoin().isPresent() && randomBoolean()) { newOptionalJoin = Optional.empty(); } else { newOptionalJoin = Optional.of( new Join( joinRequest.getSourceNode(), createNode(randomAlphaOfLength(10)), randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong() ) ); } return new JoinRequest(joinRequest.getSourceNode(), joinRequest.getMinimumTerm(), newOptionalJoin); } } ); } public ClusterState randomClusterState() { return CoordinationStateTests.clusterState( randomNonNegativeLong(), randomNonNegativeLong(), createNode(randomAlphaOfLength(10)), new CoordinationMetadata.VotingConfiguration(Sets.newHashSet(generateRandomStringArray(10, 10, false))), new CoordinationMetadata.VotingConfiguration(Sets.newHashSet(generateRandomStringArray(10, 10, false))), randomLong() ); } public void testPreVoteRequestEqualsHashCodeSerialization() { PreVoteRequest initialPreVoteRequest = new PreVoteRequest(createNode(randomAlphaOfLength(10)), randomNonNegativeLong()); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialPreVoteRequest, (CopyFunction) preVoteRequest -> copyWriteable(preVoteRequest, writableRegistry(), PreVoteRequest::new), preVoteRequest -> { if (randomBoolean()) { return new PreVoteRequest(createNode(randomAlphaOfLength(10)), preVoteRequest.getCurrentTerm()); } else { return new PreVoteRequest(preVoteRequest.getSourceNode(), randomNonNegativeLong()); } } ); } public void testPreVoteResponseEqualsHashCodeSerialization() { long currentTerm = randomNonNegativeLong(); PreVoteResponse initialPreVoteResponse = new PreVoteResponse( currentTerm, randomLongBetween(1, currentTerm), randomNonNegativeLong() ); // Note: the explicit cast of the CopyFunction is needed for some IDE (specifically Eclipse 4.8.0) to infer the right type EqualsHashCodeTestUtils.checkEqualsAndHashCode( initialPreVoteResponse, (CopyFunction) preVoteResponse -> copyWriteable(preVoteResponse, writableRegistry(), PreVoteResponse::new), preVoteResponse -> { switch (randomInt(2)) { case 0: assumeTrue("last-accepted term is Long.MAX_VALUE", preVoteResponse.getLastAcceptedTerm() < Long.MAX_VALUE); return new PreVoteResponse( randomValueOtherThan( preVoteResponse.getCurrentTerm(), () -> randomLongBetween(preVoteResponse.getLastAcceptedTerm(), Long.MAX_VALUE) ), preVoteResponse.getLastAcceptedTerm(), preVoteResponse.getLastAcceptedVersion() ); case 1: assumeTrue("current term is 1", 1 < preVoteResponse.getCurrentTerm()); return new PreVoteResponse( preVoteResponse.getCurrentTerm(), randomValueOtherThan( preVoteResponse.getLastAcceptedTerm(), () -> randomLongBetween(1, preVoteResponse.getCurrentTerm()) ), preVoteResponse.getLastAcceptedVersion() ); case 2: return new PreVoteResponse( preVoteResponse.getCurrentTerm(), preVoteResponse.getLastAcceptedTerm(), randomValueOtherThan(preVoteResponse.getLastAcceptedVersion(), OpenSearchTestCase::randomNonNegativeLong) ); default: throw new AssertionError(); } } ); } }