-
Notifications
You must be signed in to change notification settings - Fork 60
check-mysql-replication-status: Lag flapping protection #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
821b7ce
824cfae
ee78dca
7886af3
8793fdc
6e648d8
2bcb51d
ce47362
eddde67
86d7e0f
67c3823
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| #!/usr/bin/env ruby | ||
| # | ||
| # check-mysql-replication-status_spec | ||
| # | ||
| # DESCRIPTION: | ||
| # rspec tests for check-mysql-replication-status | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for writing tests, honestly I keep maintaining all these plugins and its a lot of work, it really helps when there are tests because I won't pretend to know every service in as much detail as all the awesome people (like yourself) that know them. The biggest bang for buck testing IMHO opinion is integration testing. I have written a blog post on writing integration tests for infrastructure: https://blog.sensuapp.org/writing-sensu-plugin-tests-with-test-kitchen-and-serverspec-b646d2eeee51 if you want any ideas or help please feel free to hit me up in slack on tag me in an issue/pr.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see an issue with my choice of unit test - since the checkscript itself is I didn't come up with this pattern for a checkscript unit test myself, just borrowed it from another plugin's test. Any suggestions how to solve this?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this might be what you are looking for: https://github.com/sensu-plugins/sensu-plugins-rabbitmq/blob/7.0.0/test/spec_helper.rb#L7-L27 |
||
| # | ||
| # OUTPUT: | ||
| # RSpec testing output: passes and failures info | ||
| # | ||
| # PLATFORMS: | ||
| # Linux | ||
| # | ||
| # DEPENDENCIES: | ||
| # rspec | ||
| # | ||
| # USAGE: | ||
| # For Rspec Testing | ||
| # | ||
| # NOTES: | ||
| # For Rspec Testing | ||
| # | ||
| # LICENSE: | ||
| # Copyright 2018 Jan Kunzmann, Erasys GmbH <jan.kunzmann@erasys.de> | ||
| # Released under the same terms as Sensu (the MIT license); see LICENSE | ||
| # for details. | ||
| # | ||
|
|
||
| require_relative '../bin/check-mysql-replication-status' | ||
| require_relative './spec_helper.rb' | ||
|
|
||
| # rubocop:disable Metrics/BlockLength | ||
| describe CheckMysqlReplicationStatus do | ||
| let(:checker) { described_class.new } | ||
| let(:exit_code) { nil } | ||
|
|
||
| before(:each) do | ||
| def checker.ok(*_args) | ||
| exit 0 | ||
| end | ||
|
|
||
| def checker.warning(*_args) | ||
| exit 1 | ||
| end | ||
|
|
||
| def checker.critical(*_args) | ||
| exit 2 | ||
| end | ||
| end | ||
|
|
||
| [ | ||
| # IO Thread status | SQL Thread status | Lag | Expected exit code | Expected reporting level | ||
| ['Yes', 'Yes', 0, 0, :ok], | ||
| ['No', 'Yes', nil, 2, :critical], | ||
| ['Yes', 'No', nil, 2, :critical], | ||
| ['No', 'No', nil, 2, :critical], | ||
| ['Yes', 'Yes', 900, 0, :ok], | ||
| ['Yes', 'Yes', 901, 1, :warning], | ||
| ['Yes', 'Yes', 1800, 1, :warning], | ||
| ['Yes', 'Yes', 1801, 2, :critical], | ||
| ].each do |testdata| | ||
| it "returns #{testdata[4]} for default thresholds" do | ||
| slave_status_row = { | ||
| 'Slave_IO_State' => '', | ||
| 'Slave_IO_Running' => testdata[0], | ||
| 'Slave_SQL_Running' => testdata[1], | ||
| 'Last_IO_Error' => '', | ||
| 'Last_SQL_Error' => '', | ||
| 'Seconds_Behind_Master' => testdata[2] | ||
| } | ||
| allow(checker).to receive(:open_connection) # do nothing | ||
| allow(checker).to receive(:query_slave_status).and_return slave_status_row | ||
| expect(checker).to receive(testdata[4]).once.and_call_original | ||
| begin | ||
| checker.run | ||
| rescue SystemExit => e | ||
| exit_code = e.status | ||
| end | ||
| expect(exit_code).to eq testdata[3] | ||
| end | ||
| end | ||
|
|
||
| [ | ||
| # Lag after outlier | Configured reporting level | Exit code | Expected reporting level | Expected message | ||
| [0, :ok, 0, :ok, 'slave running: true, replication delayed by 0, with max. outlier at 100000'], | ||
| [99_999, :ok, 2, :critical, 'replication delayed by 99999, with max. outlier at 100000'], | ||
| [0, :critical, 2, :critical, 'replication delayed by 0, with max. outlier at 100000'], | ||
| ].each do |testdata| | ||
| it "sleeps with lag outlier protection and returns #{testdata[3]} (using default thresholds)" do | ||
| checker.config[:lag_outlier_retry] = 1 | ||
| checker.config[:lag_outlier_sleep] = 10 | ||
| checker.config[:lag_outlier_report] = testdata[1] | ||
|
|
||
| slave_status_row = [ | ||
| { | ||
| 'Slave_IO_State' => '', | ||
| 'Slave_IO_Running' => 'Yes', | ||
| 'Slave_SQL_Running' => 'Yes', | ||
| 'Last_IO_Error' => '', | ||
| 'Last_SQL_Error' => '', | ||
| 'Seconds_Behind_Master' => 100_000 | ||
| }, | ||
| { | ||
| 'Slave_IO_State' => '', | ||
| 'Slave_IO_Running' => 'Yes', | ||
| 'Slave_SQL_Running' => 'Yes', | ||
| 'Last_IO_Error' => '', | ||
| 'Last_SQL_Error' => '', | ||
| 'Seconds_Behind_Master' => testdata[0] | ||
| } | ||
| ] | ||
|
|
||
| allow(checker).to receive(:open_connection) # do nothing | ||
| allow(checker).to receive(:query_slave_status).and_return slave_status_row[0], slave_status_row[1] | ||
| expect(checker).to receive(:sleep).with(10) | ||
| expect(checker).to receive(testdata[3]).with(testdata[4]).once.and_call_original | ||
| begin | ||
| checker.run | ||
| rescue SystemExit => e | ||
| exit_code = e.status | ||
| end | ||
| expect(exit_code).to eq testdata[2] | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,21 @@ | ||
| require 'codeclimate-test-reporter' | ||
| CodeClimate::TestReporter.start | ||
| RSpec.configure do |c| | ||
| # Sensu plugins run in the context of an at_exit handler. This prevents | ||
| # code-under-test from being run at the end of the rspec suite. | ||
| c.before(:each) do | ||
| Sensu::Plugin::CLI.class_eval do | ||
| # PluginStub | ||
| class PluginStub | ||
| def run; end | ||
|
|
||
| def ok(*); end | ||
|
|
||
| def warning(*); end | ||
|
|
||
| def critical(*); end | ||
|
|
||
| def unknown(*); end | ||
| end | ||
| class_variable_set(:@@autorun, PluginStub) | ||
| end | ||
| end | ||
| end |
Uh oh!
There was an error while loading. Please reload this page.