|
require "rails_helper" |
|
|
|
RSpec.describe CloudwatchLogs::Client, type: :client do |
|
let(:query_id) { 'query_id' } |
|
let(:query_status) { 'Complete' } |
|
let(:response) { double(:response, status: query_status, results: results) } |
|
|
|
let(:results) do |
|
[ |
|
[ logs_struct_for('ip', '192.168.1.1'), logs_struct_for('user_id', '1'), logs_struct_for('count', '10') ], |
|
[ logs_struct_for('ip', '192.168.2.1'), logs_struct_for('user_id', '2'), logs_struct_for('count', '20') ], |
|
[ logs_struct_for('ip', '192.168.2.1'), logs_struct_for('user_id', '1'), logs_struct_for('count', '30') ], |
|
] |
|
end |
|
|
|
let(:parsed_results) do |
|
[ |
|
['ip', 'user_id', 'count'], |
|
['192.168.1.1', '1', '10'], |
|
['192.168.2.1', '2', '20'], |
|
['192.168.2.1', '1', '30'], |
|
] |
|
end |
|
|
|
let(:query_results) { { status: query_status, results: parsed_results, timestamp: Time.now.to_i }.with_indifferent_access } |
|
|
|
around do |example| |
|
Timecop.freeze(Time.current, &example) |
|
end |
|
|
|
# Warning: use only `scan_each` on controled environments. Never in prod |
|
before(:each) { $redis_client.scan_each(match: "#{described_class::KEY_PREFIX}*") { |key| redis_object.del(key) } } |
|
|
|
describe '#start_query' do |
|
let(:options) { { options: '' } } |
|
let(:query_response) { double(:response, query_id: query_id) } |
|
|
|
it 'sends the options to the original client' do |
|
expect($cloudwatch_logs).to receive(:start_query).with(options).and_return(query_response) |
|
expect(described_class.start_query(options)).to eq(query_id) |
|
end |
|
end |
|
|
|
describe '#get_query_results' do |
|
it 'queries the original client and parses the results' do |
|
expect($cloudwatch_logs).to receive(:get_query_results).with(query_id: query_id).and_return(response) |
|
expect(described_class.get_query_results(query_id)).to eq(query_results) |
|
end |
|
end |
|
|
|
describe '#get_cached_query_results' do |
|
let(:cache_key) { "#{described_class::KEY_PREFIX}/#{query_id}" } |
|
|
|
context 'when it is not cached yet' do |
|
it 'caches the results if the status is "Complete"' do |
|
expect($redis_client.get(cache_key)).to eq(nil) |
|
expect($cloudwatch_logs).to receive(:get_query_results).with(query_id: query_id).and_return(response) |
|
|
|
expect(described_class.get_cached_query_results(query_id)).to eq(query_results) |
|
expect($redis_client.get(cache_key)).to eq(query_results.to_json) |
|
end |
|
|
|
context 'when the status is "Running"' do |
|
let(:query_status) { 'Running' } |
|
|
|
it 'does not cache the results' do |
|
expect($redis_client.get(cache_key)).to eq(nil) |
|
expect($cloudwatch_logs).to receive(:get_query_results).with(query_id: query_id).and_return(response) |
|
|
|
expect(described_class.get_cached_query_results(query_id)).to eq(query_results) |
|
expect($redis_client.get(cache_key)).to eq(nil) |
|
end |
|
end |
|
end |
|
|
|
context 'when it is already cached' do |
|
it 'returns the cached result' do |
|
$redis_general_purpose.set(cache_key, query_results.to_json) |
|
expect($cloudwatch_logs).not_to receive(:get_query_results) |
|
|
|
expect(described_class.get_cached_query_results(query_id)).to eq(query_results) |
|
expect($redis_client.get(cache_key)).to eq(query_results.to_json) |
|
end |
|
end |
|
end |
|
|
|
def logs_struct_for(field, value) |
|
double('ResultField', field: field, value: value) |
|
end |
|
end |