aboutsummaryrefslogtreecommitdiffstats
path: root/storage/src/tests/distributor/putoperationtest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/src/tests/distributor/putoperationtest.cpp')
-rw-r--r--storage/src/tests/distributor/putoperationtest.cpp70
1 files changed, 64 insertions, 6 deletions
diff --git a/storage/src/tests/distributor/putoperationtest.cpp b/storage/src/tests/distributor/putoperationtest.cpp
index f5bacfae252..16d5dcf3b25 100644
--- a/storage/src/tests/distributor/putoperationtest.cpp
+++ b/storage/src/tests/distributor/putoperationtest.cpp
@@ -72,11 +72,11 @@ public:
}
void sendPut(std::shared_ptr<api::PutCommand> msg) {
- op.reset(new PutOperation(getExternalOperationHandler(),
- getDistributorBucketSpace(),
- msg,
- getDistributor().getMetrics().
- puts[msg->getLoadType()]));
+ op = std::make_unique<PutOperation>(getExternalOperationHandler(),
+ getDistributorBucketSpace(),
+ msg,
+ getDistributor().getMetrics().
+ puts[msg->getLoadType()]);
op->start(_sender, framework::MilliSecTime(0));
}
@@ -88,9 +88,11 @@ public:
return std::make_shared<Document>(doc_type(), DocumentId(vespalib::make_string("id:%s:testdoctype1::%s", ns, id)));
}
- std::shared_ptr<api::PutCommand> createPut(Document::SP doc) const {
+ static std::shared_ptr<api::PutCommand> createPut(Document::SP doc) {
return std::make_shared<api::PutCommand>(makeDocumentBucket(document::BucketId(0)), std::move(doc), 100);
}
+
+ void set_up_3_nodes_and_send_put_with_create_bucket_acks();
};
PutOperationTest::~PutOperationTest() = default;
@@ -624,4 +626,60 @@ TEST_F(PutOperationTest, replica_not_implicitly_activated_when_activation_is_dis
do_test_creation_with_bucket_activation_disabled(true);
}
+void PutOperationTest::set_up_3_nodes_and_send_put_with_create_bucket_acks() {
+ setupDistributor(3, 3, "storage:3 distributor:1");
+
+ Document::SP doc(createDummyDocument("test", "test"));
+ sendPut(createPut(doc));
+
+ // Include CreateBucket to ensure we don't count it towards Put ACK majorities
+ ASSERT_EQ("Create bucket => 2,Create bucket => 1,Create bucket => 0,"
+ "Put => 2,Put => 1,Put => 0",
+ _sender.getCommands(true));
+
+ // ACK all CreateBuckets
+ for (uint32_t i = 0; i < 3; ++i) {
+ sendReply(i);
+ }
+}
+
+TEST_F(PutOperationTest, majority_ack_with_minority_tas_failure_returns_success) {
+ ASSERT_NO_FATAL_FAILURE(set_up_3_nodes_and_send_put_with_create_bucket_acks());
+ // Majority ACK, minority NACK
+ sendReply(3);
+ sendReply(4, api::ReturnCode::TEST_AND_SET_CONDITION_FAILED);
+ sendReply(5);
+
+ ASSERT_EQ("PutReply(id:test:testdoctype1::test, "
+ "BucketId(0x0000000000000000), "
+ "timestamp 100) ReturnCode(NONE)",
+ _sender.getLastReply());
+}
+
+TEST_F(PutOperationTest, minority_ack_with_majority_tas_failure_returns_tas_failure) {
+ ASSERT_NO_FATAL_FAILURE(set_up_3_nodes_and_send_put_with_create_bucket_acks());
+ // Minority ACK, majority NACK
+ sendReply(3);
+ sendReply(4, api::ReturnCode::TEST_AND_SET_CONDITION_FAILED);
+ sendReply(5, api::ReturnCode::TEST_AND_SET_CONDITION_FAILED);
+
+ ASSERT_EQ("PutReply(id:test:testdoctype1::test, "
+ "BucketId(0x0000000000000000), "
+ "timestamp 100) ReturnCode(TEST_AND_SET_CONDITION_FAILED)",
+ _sender.getLastReply());
+}
+
+TEST_F(PutOperationTest, minority_failure_override_not_in_effect_for_non_tas_errors) {
+ ASSERT_NO_FATAL_FAILURE(set_up_3_nodes_and_send_put_with_create_bucket_acks());
+ // Minority ACK, majority NACK. But non-TaS failure.
+ sendReply(3);
+ sendReply(4, api::ReturnCode::ABORTED);
+ sendReply(5);
+
+ ASSERT_EQ("PutReply(id:test:testdoctype1::test, "
+ "BucketId(0x0000000000000000), "
+ "timestamp 100) ReturnCode(ABORTED)",
+ _sender.getLastReply());
+}
+
}