2020-04-08 14:13:33 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe ::PodLogs::ElasticsearchService do
|
|
|
|
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*') }
|
|
|
|
let(:namespace) { 'autodevops-deploy-9-production' }
|
|
|
|
|
|
|
|
let(:pod_name) { 'pod-1' }
|
|
|
|
let(:container_name) { 'container-1' }
|
|
|
|
let(:search) { 'foo -bar' }
|
|
|
|
let(:start_time) { '2019-01-02T12:13:14+02:00' }
|
|
|
|
let(:end_time) { '2019-01-03T12:13:14+02:00' }
|
|
|
|
let(:cursor) { '9999934,1572449784442' }
|
|
|
|
let(:params) { {} }
|
|
|
|
let(:expected_logs) do
|
|
|
|
[
|
|
|
|
{ message: "Log 1", timestamp: "2019-12-13T14:04:22.123456Z" },
|
|
|
|
{ message: "Log 2", timestamp: "2019-12-13T14:04:23.123456Z" },
|
|
|
|
{ message: "Log 3", timestamp: "2019-12-13T14:04:24.123456Z" }
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
2020-04-22 19:07:51 +05:30
|
|
|
let(:raw_pods) do
|
|
|
|
[
|
|
|
|
{
|
|
|
|
name: pod_name,
|
|
|
|
container_names: [container_name, "#{container_name}-1"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
subject { described_class.new(cluster, namespace, params: params) }
|
|
|
|
|
2020-04-22 19:07:51 +05:30
|
|
|
describe '#get_raw_pods' do
|
|
|
|
before do
|
|
|
|
create(:clusters_applications_elastic_stack, :installed, cluster: cluster)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with elasticsearch response' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(Elasticsearch::Transport::Client.new)
|
|
|
|
allow_any_instance_of(::Gitlab::Elasticsearch::Logs::Pods)
|
|
|
|
.to receive(:pods)
|
|
|
|
.with(namespace)
|
|
|
|
.and_return(raw_pods)
|
|
|
|
|
|
|
|
result = subject.send(:get_raw_pods, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
expect(result[:raw_pods]).to eq(raw_pods)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns an error when ES is unreachable' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(nil)
|
|
|
|
|
|
|
|
result = subject.send(:get_raw_pods, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Unable to connect to Elasticsearch')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'handles server errors from elasticsearch' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(Elasticsearch::Transport::Client.new)
|
|
|
|
allow_any_instance_of(::Gitlab::Elasticsearch::Logs::Pods)
|
|
|
|
.to receive(:pods)
|
|
|
|
.and_raise(Elasticsearch::Transport::Transport::Errors::ServiceUnavailable.new)
|
|
|
|
|
|
|
|
result = subject.send(:get_raw_pods, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Elasticsearch returned status code: ServiceUnavailable')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
describe '#check_times' do
|
|
|
|
context 'with start and end provided and valid' do
|
|
|
|
let(:params) do
|
|
|
|
{
|
2020-04-22 19:07:51 +05:30
|
|
|
'start_time' => start_time,
|
|
|
|
'end_time' => end_time
|
2020-04-08 14:13:33 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with times' do
|
|
|
|
result = subject.send(:check_times, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:success)
|
2020-04-22 19:07:51 +05:30
|
|
|
expect(result[:start_time]).to eq(start_time)
|
|
|
|
expect(result[:end_time]).to eq(end_time)
|
2020-04-08 14:13:33 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with start and end not provided' do
|
|
|
|
let(:params) do
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with nothing else' do
|
|
|
|
result = subject.send(:check_times, {})
|
|
|
|
|
|
|
|
expect(result.keys.length).to eq(1)
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with start valid and end invalid' do
|
|
|
|
let(:params) do
|
|
|
|
{
|
2020-04-22 19:07:51 +05:30
|
|
|
'start_time' => start_time,
|
|
|
|
'end_time' => 'invalid date'
|
2020-04-08 14:13:33 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns error' do
|
|
|
|
result = subject.send(:check_times, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Invalid start or end time format')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with start invalid and end valid' do
|
|
|
|
let(:params) do
|
|
|
|
{
|
2020-04-22 19:07:51 +05:30
|
|
|
'start_time' => 'invalid date',
|
|
|
|
'end_time' => end_time
|
2020-04-08 14:13:33 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns error' do
|
|
|
|
result = subject.send(:check_times, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Invalid start or end time format')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#check_search' do
|
|
|
|
context 'with search provided and valid' do
|
|
|
|
let(:params) do
|
|
|
|
{
|
|
|
|
'search' => search
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with search' do
|
|
|
|
result = subject.send(:check_search, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
expect(result[:search]).to eq(search)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with search not provided' do
|
|
|
|
let(:params) do
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with nothing else' do
|
|
|
|
result = subject.send(:check_search, {})
|
|
|
|
|
|
|
|
expect(result.keys.length).to eq(1)
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#check_cursor' do
|
|
|
|
context 'with cursor provided and valid' do
|
|
|
|
let(:params) do
|
|
|
|
{
|
|
|
|
'cursor' => cursor
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with cursor' do
|
|
|
|
result = subject.send(:check_cursor, {})
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
expect(result[:cursor]).to eq(cursor)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with cursor not provided' do
|
|
|
|
let(:params) do
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns success with nothing else' do
|
|
|
|
result = subject.send(:check_cursor, {})
|
|
|
|
|
|
|
|
expect(result.keys.length).to eq(1)
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#pod_logs' do
|
|
|
|
let(:result_arg) do
|
|
|
|
{
|
|
|
|
pod_name: pod_name,
|
|
|
|
container_name: container_name,
|
|
|
|
search: search,
|
2020-04-22 19:07:51 +05:30
|
|
|
start_time: start_time,
|
|
|
|
end_time: end_time,
|
2020-04-08 14:13:33 +05:30
|
|
|
cursor: cursor
|
|
|
|
}
|
|
|
|
end
|
|
|
|
let(:expected_cursor) { '9999934,1572449784442' }
|
|
|
|
|
|
|
|
before do
|
|
|
|
create(:clusters_applications_elastic_stack, :installed, cluster: cluster)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the logs' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(Elasticsearch::Transport::Client.new)
|
2020-04-22 19:07:51 +05:30
|
|
|
allow_any_instance_of(::Gitlab::Elasticsearch::Logs::Lines)
|
2020-04-08 14:13:33 +05:30
|
|
|
.to receive(:pod_logs)
|
2020-04-22 19:07:51 +05:30
|
|
|
.with(namespace, pod_name: pod_name, container_name: container_name, search: search, start_time: start_time, end_time: end_time, cursor: cursor)
|
2020-04-08 14:13:33 +05:30
|
|
|
.and_return({ logs: expected_logs, cursor: expected_cursor })
|
|
|
|
|
|
|
|
result = subject.send(:pod_logs, result_arg)
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:success)
|
|
|
|
expect(result[:logs]).to eq(expected_logs)
|
|
|
|
expect(result[:cursor]).to eq(expected_cursor)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns an error when ES is unreachable' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(nil)
|
|
|
|
|
|
|
|
result = subject.send(:pod_logs, result_arg)
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Unable to connect to Elasticsearch')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'handles server errors from elasticsearch' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(Elasticsearch::Transport::Client.new)
|
2020-04-22 19:07:51 +05:30
|
|
|
allow_any_instance_of(::Gitlab::Elasticsearch::Logs::Lines)
|
2020-04-08 14:13:33 +05:30
|
|
|
.to receive(:pod_logs)
|
|
|
|
.and_raise(Elasticsearch::Transport::Transport::Errors::ServiceUnavailable.new)
|
|
|
|
|
|
|
|
result = subject.send(:pod_logs, result_arg)
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Elasticsearch returned status code: ServiceUnavailable')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'handles cursor errors from elasticsearch' do
|
|
|
|
allow_any_instance_of(::Clusters::Applications::ElasticStack)
|
|
|
|
.to receive(:elasticsearch_client)
|
|
|
|
.and_return(Elasticsearch::Transport::Client.new)
|
2020-04-22 19:07:51 +05:30
|
|
|
allow_any_instance_of(::Gitlab::Elasticsearch::Logs::Lines)
|
2020-04-08 14:13:33 +05:30
|
|
|
.to receive(:pod_logs)
|
2020-04-22 19:07:51 +05:30
|
|
|
.and_raise(::Gitlab::Elasticsearch::Logs::Lines::InvalidCursor.new)
|
2020-04-08 14:13:33 +05:30
|
|
|
|
|
|
|
result = subject.send(:pod_logs, result_arg)
|
|
|
|
|
|
|
|
expect(result[:status]).to eq(:error)
|
|
|
|
expect(result[:message]).to eq('Invalid cursor value provided')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|