Commit 797046e3 authored by Matija Čupić's avatar Matija Čupić

Reconcile differences in lib/gitlab/ci/external/file

parent 6a8133b9
module Gitlab
module Ci
module External
module File
class Base
YAML_WHITELIST_EXTENSION = /(yml|yaml)$/i.freeze
def initialize(location, opts = {})
@location = location
end
def valid?
location.match(YAML_WHITELIST_EXTENSION) && content
end
def content
raise NotImplementedError, 'content must be implemented and return a string or nil'
end
def error_message
raise NotImplementedError, 'error_message must be implemented and return a string'
end
end
end
end
end
end
......@@ -2,27 +2,28 @@ module Gitlab
module Ci
module External
module File
class Local
attr_reader :location, :project, :branch_name
class Local < Base
attr_reader :location, :project, :sha
def initialize(location, opts = {})
@location = location
super
@project = opts.fetch(:project)
@sha = opts.fetch(:sha)
end
def valid?
local_file_content
def content
@content ||= fetch_local_content
end
def content
local_file_content
def error_message
"Local file '#{location}' is not valid."
end
private
def local_file_content
@local_file_content ||= project.repository.blob_data_at(sha, location)
def fetch_local_content
project.repository.blob_data_at(sha, location)
end
end
end
......
......@@ -2,29 +2,25 @@ module Gitlab
module Ci
module External
module File
class Remote
class Remote < Base
include Gitlab::Utils::StrongMemoize
attr_reader :location
def initialize(location, opts = {})
@location = location
end
def valid?
::Gitlab::UrlSanitizer.valid?(location) && content
end
def content
return @content if defined?(@content)
@content = strong_memoize(:content) do
begin
HTTParty.get(location)
rescue HTTParty::Error, Timeout::Error
false
Gitlab::HTTP.get(location)
rescue Gitlab::HTTP::Error, Timeout::Error, SocketError, Gitlab::HTTP::BlockedUrlError
nil
end
end
end
def error_message
"Remote file '#{location}' is not valid."
end
end
end
end
......
require 'fast_spec_helper'
require 'spec_helper'
describe Gitlab::Ci::External::File::Local do
let(:project) { create(:project, :repository) }
let(:local_file) { described_class.new(location, { project: project, sha: '12345' }) }
describe "#valid?" do
describe '#valid?' do
context 'when is a valid local path' do
let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' }
before do
allow_any_instance_of(described_class).to receive(:local_file_content).and_return("image: 'ruby2:2'")
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return("image: 'ruby2:2'")
end
it 'should return true' do
......@@ -25,29 +25,52 @@ describe Gitlab::Ci::External::File::Local do
end
end
describe "#content" do
context 'when is not a yaml file' do
let(:location) { '/config/application.rb' }
it 'should return false' do
expect(local_file.valid?).to be_falsy
end
end
end
describe '#content' do
context 'with a a valid file' do
let(:local_file_content) do
<<~HEREDOC
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- ruby -v
- which ruby
- gem install bundler --no-ri --no-rdoc
- bundle install --jobs $(nproc) "${FLAGS[@]}"
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- ruby -v
- which ruby
- gem install bundler --no-ri --no-rdoc
- bundle install --jobs $(nproc) "${FLAGS[@]}"
HEREDOC
end
let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' }
before do
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return(local_file_content)
end
context 'with a local file' do
let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
it 'should return the content of the file' do
expect(local_file.content).to eq(local_file_content)
end
end
before do
allow_any_instance_of(described_class).to receive(:local_file_content).and_return(local_file_content)
end
context 'with an invalid file' do
let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
it 'should return the content of the file' do
expect(local_file.content).to eq(local_file_content)
end
it 'should be nil' do
expect(local_file.content).to be_nil
end
end
end
describe '#error_message' do
let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
it 'should return an error message' do
expect(local_file.error_message).to eq("Local file '#{location}' is not valid.")
end
end
end
require 'fast_spec_helper'
require 'spec_helper'
describe Gitlab::Ci::External::File::Remote do
let(:remote_file) { described_class.new(location) }
......@@ -25,7 +25,7 @@ describe Gitlab::Ci::External::File::Remote do
end
end
context 'when is not a valid remote url' do
context 'with an irregular url' do
let(:location) { 'not-valid://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' }
it 'should return false' do
......@@ -35,13 +35,29 @@ describe Gitlab::Ci::External::File::Remote do
context 'with a timeout' do
before do
allow(HTTParty).to receive(:get).and_raise(Timeout::Error)
allow(Gitlab::HTTP).to receive(:get).and_raise(Timeout::Error)
end
it 'should be falsy' do
expect(remote_file.valid?).to be_falsy
end
end
context 'when is not a yaml file' do
let(:location) { 'https://asdasdasdaj48ggerexample.com' }
it 'should be falsy' do
expect(remote_file.valid?).to be_falsy
end
end
context 'with an internal url' do
let(:location) { 'http://localhost:8080' }
it 'should be falsy' do
expect(remote_file.valid?).to be_falsy
end
end
end
describe "#content" do
......@@ -57,12 +73,40 @@ describe Gitlab::Ci::External::File::Remote do
context 'with a timeout' do
before do
allow(HTTParty).to receive(:get).and_raise(Timeout::Error)
allow(Gitlab::HTTP).to receive(:get).and_raise(Timeout::Error)
end
it 'should be falsy' do
expect(remote_file.content).to be_falsy
end
end
context 'with an invalid remote url' do
let(:location) { 'https://asdasdasdaj48ggerexample.com' }
before do
WebMock.stub_request(:get, location).to_raise(SocketError.new('Some HTTP error'))
end
it 'should be nil' do
expect(remote_file.content).to be_nil
end
end
context 'with an internal url' do
let(:location) { 'http://localhost:8080' }
it 'should be nil' do
expect(remote_file.content).to be_nil
end
end
end
describe "#error_message" do
let(:location) { 'not-valid://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' }
it 'should return an error message' do
expect(remote_file.error_message).to eq("Remote file '#{location}' is not valid.")
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