1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
# frozen_string_literal: true
# rubocop:todo all
require 'spec_helper'
describe Mongo::Error::OperationFailure do
describe '#write_concern_error' do
# Fail point will work on 4.0 mongod but requires 4.2 for mongos
min_server_fcv '4.2'
# Fail point must be set on the same server to which the query is sent
require_no_multi_mongos
# https://github.com/mongodb/specifications/commit/7745234f93039a83ae42589a6c0cdbefcffa32fa
let(:fail_point_command) do
{
"configureFailPoint": "failCommand",
"data": {
"failCommands": ["insert"],
"writeConcernError": {
"code": 100,
"codeName": "UnsatisfiableWriteConcern",
"errmsg": "Not enough data-bearing nodes",
"errInfo": {
"writeConcern": {
"w": 2,
"wtimeout": 0,
"provenance": "clientSupplied"
}
}
}
},
"mode": { "times": 1 }
}
end
it 'exposes all server-provided fields' do
authorized_client.use('admin').command(fail_point_command)
begin
authorized_client['foo'].insert_one(test: 1)
rescue Mongo::Error::OperationFailure::Family => exc
expect(exc.details).to eq(exc.document['writeConcernError']['errInfo'])
expect(exc.server_message).to eq(exc.document['writeConcernError']['errmsg'])
expect(exc.code).to eq(exc.document['writeConcernError']['code'])
else
fail 'Expected an OperationFailure'
end
exc.write_concern_error_document.should == {
'code' => 100,
'codeName' => 'UnsatisfiableWriteConcern',
'errmsg' => 'Not enough data-bearing nodes',
'errInfo' => {
'writeConcern' => {
'w' => 2,
'wtimeout' => 0,
'provenance' => 'clientSupplied',
},
},
}
end
end
describe 'WriteError details' do
min_server_fcv '5.0'
let(:subscriber) { Mrss::EventSubscriber.new }
let(:subscribed_client) do
authorized_client.tap do |client|
client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
end
end
let(:collection_name) { 'write_error_prose_spec' }
let(:collection) do
subscribed_client[:collection_name].drop
subscribed_client[:collection_name,
{
'validator' => {
'x' => { '$type' => 'string' },
}
}].create
subscribed_client[:collection_name]
end
context 'when there is a write error' do
it 'succeeds and prints the error' do
begin
collection.insert_one({x: 1})
rescue Mongo::Error::OperationFailure::Family => e
insert_events = subscriber.succeeded_events.select { |e| e.command_name == "insert" }
expect(insert_events.length).to eq 1
expect(e.message).to match(/\[#{e.code}(:.*)?\].+ -- .+/)
expect(e.details).to eq(e.document['writeErrors'][0]['errInfo'])
expect(e.server_message).to eq(e.document['writeErrors'][0]['errmsg'])
expect(e.code).to eq(e.document['writeErrors'][0]['code'])
expect(e.code).to eq 121
expect(e.details).to eq(insert_events[0].reply['writeErrors'][0]['errInfo'])
else
fail 'Expected an OperationFailure'
end
end
end
end
end
|