Commit 3a4cb6d6 authored by Kamil Trzciński's avatar Kamil Trzciński Committed by Grzegorz Bizon

Bring backward compatibility for request profiles

It seems that we missed the backward compatibility support
for profiles in the existing folder.

This commit also fixes some specs to be idempotent
and work in a temporary directory which not always
seems to be the case.

This commit also brings the profile_spec.rb which seems
to be missing.
parent 5e102f17
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
class Admin::RequestsProfilesController < Admin::ApplicationController class Admin::RequestsProfilesController < Admin::ApplicationController
def index def index
@profile_token = Gitlab::RequestProfiler.profile_token @profile_token = Gitlab::RequestProfiler.profile_token
@profiles = Gitlab::RequestProfiler::Profile.all.group_by(&:request_path) @profiles = Gitlab::RequestProfiler.all.group_by(&:request_path)
end end
def show def show
clean_name = Rack::Utils.clean_path_info(params[:name]) clean_name = Rack::Utils.clean_path_info(params[:name])
profile = Gitlab::RequestProfiler::Profile.find(clean_name) profile = Gitlab::RequestProfiler.find(clean_name)
unless profile && profile.content_type unless profile && profile.content_type
return redirect_to admin_requests_profiles_path, alert: 'Profile not found' return redirect_to admin_requests_profiles_path, alert: 'Profile not found'
......
...@@ -6,6 +6,21 @@ module Gitlab ...@@ -6,6 +6,21 @@ module Gitlab
module RequestProfiler module RequestProfiler
PROFILES_DIR = "#{Gitlab.config.shared.path}/tmp/requests_profiles".freeze PROFILES_DIR = "#{Gitlab.config.shared.path}/tmp/requests_profiles".freeze
def all
Dir["#{PROFILES_DIR}/*.{html,txt}"].map do |path|
Profile.new(File.basename(path))
end.select(&:valid?)
end
module_function :all
def find(name)
file_path = File.join(PROFILES_DIR, name)
return unless File.exist?(file_path)
Profile.new(name)
end
module_function :find
def profile_token def profile_token
Rails.cache.fetch('profile-token') do Rails.cache.fetch('profile-token') do
Devise.friendly_token Devise.friendly_token
......
...@@ -7,19 +7,6 @@ module Gitlab ...@@ -7,19 +7,6 @@ module Gitlab
alias_method :to_param, :name alias_method :to_param, :name
def self.all
Dir["#{PROFILES_DIR}/*.{html,txt}"].map do |path|
new(File.basename(path))
end
end
def self.find(name)
file_path = File.join(PROFILES_DIR, name)
return unless File.exist?(file_path)
new(name)
end
def initialize(name) def initialize(name)
@name = name @name = name
@file_path = File.join(PROFILES_DIR, name) @file_path = File.join(PROFILES_DIR, name)
...@@ -27,8 +14,8 @@ module Gitlab ...@@ -27,8 +14,8 @@ module Gitlab
set_attributes set_attributes
end end
def content def valid?
File.read("#{PROFILES_DIR}/#{name}") @request_path.present?
end end
def content_type def content_type
...@@ -43,11 +30,13 @@ module Gitlab ...@@ -43,11 +30,13 @@ module Gitlab
private private
def set_attributes def set_attributes
_, path, timestamp, profile_mode, type = name.split(/(.*)_(\d+)_(.*)\.(html|txt)$/) matches = name.match(/^(?<path>.*)_(?<timestamp>\d+)(_(?<profile_mode>\w+))?\.(?<type>html|txt)$/)
@request_path = path.tr('|', '/') return unless matches
@time = Time.at(timestamp.to_i).utc
@profile_mode = profile_mode @request_path = matches[:path].tr('|', '/')
@type = type @time = Time.at(matches[:timestamp].to_i).utc
@profile_mode = matches[:profile_mode] || 'unknown'
@type = matches[:type]
end end
end end
end end
......
...@@ -23,7 +23,7 @@ describe Admin::RequestsProfilesController do ...@@ -23,7 +23,7 @@ describe Admin::RequestsProfilesController do
end end
after do after do
File.unlink(test_file) FileUtils.rm_rf(tmpdir)
end end
context 'when loading HTML profile' do context 'when loading HTML profile' do
......
require 'spec_helper' require 'spec_helper'
describe 'Admin::RequestsProfilesController' do describe 'Admin::RequestsProfilesController' do
let(:tmpdir) { Dir.mktmpdir('profiler-test') }
before do before do
FileUtils.mkdir_p(Gitlab::RequestProfiler::PROFILES_DIR) stub_const('Gitlab::RequestProfiler::PROFILES_DIR', tmpdir)
sign_in(create(:admin)) sign_in(create(:admin))
end end
after do after do
Gitlab::RequestProfiler.remove_all_profiles FileUtils.rm_rf(tmpdir)
end end
describe 'GET /admin/requests_profiles' do describe 'GET /admin/requests_profiles' do
...@@ -60,6 +62,12 @@ describe 'Admin::RequestsProfilesController' do ...@@ -60,6 +62,12 @@ describe 'Admin::RequestsProfilesController' do
name: "|gitlab-org|infrastructure_#{time2.to_i}_memory.html", name: "|gitlab-org|infrastructure_#{time2.to_i}_memory.html",
created: time2, created: time2,
profile_mode: 'Memory' profile_mode: 'Memory'
},
{
request_path: '/gitlab-org/infrastructure',
name: "|gitlab-org|infrastructure_#{time2.to_i}.html",
created: time2,
profile_mode: 'Unknown'
} }
] ]
end end
......
require 'fast_spec_helper'
describe Gitlab::RequestProfiler::Profile do
let(:profile) { described_class.new(filename) }
describe '.new' do
context 'using old filename' do
let(:filename) { '|api|v4|version.txt_1562854738.html' }
it 'returns valid data' do
expect(profile).to be_valid
expect(profile.request_path).to eq('/api/v4/version.txt')
expect(profile.time).to eq(Time.at(1562854738).utc)
expect(profile.type).to eq('html')
end
end
context 'using new filename' do
let(:filename) { '|api|v4|version.txt_1563547949_execution.html' }
it 'returns valid data' do
expect(profile).to be_valid
expect(profile.request_path).to eq('/api/v4/version.txt')
expect(profile.profile_mode).to eq('execution')
expect(profile.time).to eq(Time.at(1563547949).utc)
expect(profile.type).to eq('html')
end
end
end
describe '#content_type' do
context 'when using html file' do
let(:filename) { '|api|v4|version.txt_1562854738_memory.html' }
it 'returns valid data' do
expect(profile).to be_valid
expect(profile.content_type).to eq('text/html')
end
end
context 'when using text file' do
let(:filename) { '|api|v4|version.txt_1562854738_memory.txt' }
it 'returns valid data' do
expect(profile).to be_valid
expect(profile.content_type).to eq('text/plain')
end
end
context 'when file is unknown' do
let(:filename) { '|api|v4|version.txt_1562854738_memory.xxx' }
it 'returns valid data' do
expect(profile).not_to be_valid
expect(profile.content_type).to be_nil
end
end
end
end
...@@ -13,15 +13,42 @@ describe Gitlab::RequestProfiler do ...@@ -13,15 +13,42 @@ describe Gitlab::RequestProfiler do
end end
end end
describe '.remove_all_profiles' do context 'with temporary PROFILES_DIR' do
it 'removes Gitlab::RequestProfiler::PROFILES_DIR directory' do let(:tmpdir) { Dir.mktmpdir('profiler-test') }
dir = described_class::PROFILES_DIR let(:profile_name) { '|api|v4|version.txt_1562854738_memory.html' }
FileUtils.mkdir_p(dir) let(:profile_path) { File.join(tmpdir, profile_name) }
expect(Dir.exist?(dir)).to be true before do
stub_const('Gitlab::RequestProfiler::PROFILES_DIR', tmpdir)
FileUtils.touch(profile_path)
end
after do
FileUtils.rm_rf(tmpdir)
end
describe '.remove_all_profiles' do
it 'removes Gitlab::RequestProfiler::PROFILES_DIR directory' do
described_class.remove_all_profiles
expect(Dir.exist?(tmpdir)).to be false
end
end
describe '.all' do
subject { described_class.all }
it 'returns all profiles' do
expect(subject.map(&:name)).to contain_exactly(profile_name)
end
end
describe '.find' do
subject { described_class.find(profile_name) }
described_class.remove_all_profiles it 'returns all profiles' do
expect(Dir.exist?(dir)).to be false expect(subject.name).to eq(profile_name)
end
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment