start porting api integration tests

This commit is contained in:
Sven Fuchs 2012-10-01 18:19:54 +02:00
parent 49d428dee1
commit 289f7c1486
43 changed files with 497 additions and 115 deletions

View File

@ -15,6 +15,7 @@ group :test do
gem 'rspec', '~> 2.11'
gem 'factory_girl', '~> 2.4.0'
gem 'mocha', '~> 0.12'
gem 'database_cleaner', '~> 0.8.0'
end
group :development do

View File

@ -121,6 +121,7 @@ GEM
data_migrations (0.0.1)
activerecord
rake
database_cleaner (0.8.0)
diff-lcs (1.1.3)
erubis (2.7.0)
eventmachine (1.0.0)
@ -234,6 +235,7 @@ PLATFORMS
DEPENDENCIES
bunny
database_cleaner (~> 0.8.0)
factory_girl (~> 2.4.0)
foreman
gh!

View File

@ -1,2 +1,6 @@
# Make sure we set that before everything
ENV['RACK_ENV'] ||= ENV['RAILS_ENV'] || ENV['ENV']
ENV['RAILS_ENV'] = ENV['RACK_ENV']
require 'travis/api/app'
run Travis::Api::App.new

View File

@ -1,7 +1,3 @@
# Make sure we set that before everything
ENV['RACK_ENV'] ||= ENV['RAILS_ENV'] || ENV['ENV']
ENV['RAILS_ENV'] = ENV['RACK_ENV']
require 'travis'
require 'backports'
require 'rack'

View File

@ -7,8 +7,8 @@ class Travis::Api::App
body all(params).run, type: :hooks
end
put('/:id', scope: :private) do
update(params[:hook]).run
put('/:id?', scope: :private) do
update(id: params[:id] || params[:hook][:id], active: params[:hook][:active]).run
204
end
end

View File

@ -25,9 +25,9 @@ class Travis::Api::App
options[:params] ||= params
builder = Travis::Api.builder(resource, options)
# builder || raise("could not determine a builder for #{resource}, #{options}")
resource = builder.new(resource, options[:params]).data.to_json if builder
resource = resource.to_json if resource.is_a? Hash
resource
end

View File

@ -0,0 +1,13 @@
require 'spec_helper'
describe 'Branches' do
before { Scenario.default }
let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.1+json' } }
it 'GET /branches?repository_id=:repository_id' do
response = get '/branches', { repository_id: repo.id }, headers
response.should deliver_json_for(repo.last_finished_builds_by_branches, version: 'v1', type: 'branches')
end
end

View File

@ -0,0 +1,34 @@
require 'spec_helper'
describe 'Builds' do
before { Scenario.default }
let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
let(:build) { repo.builds.first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.1+json' } }
it 'GET /builds?repository_id=1' do
response = get '/builds', { repository_id: repo.id }, headers
response.should deliver_json_for(repo.builds.was_started, version: 'v1')
end
it 'GET /builds/1' do
response = get "/builds/#{build.id}", {}, headers
response.should deliver_json_for(build, version: 'v1')
end
it 'GET /builds/1?repository_id=1' do
response = get "/builds/#{build.id}", { repository_id: repo.id }, headers
response.should deliver_json_for(build, version: 'v1')
end
xit 'GET /svenfuchs/minimal/builds' do
response = get '/svenfuchs/minimal/builds', {}, headers
response.should deliver_json_for(repo.builds, version: 'v1')
end
xit 'GET /svenfuchs/minimal/builds/1' do
response = get "/svenfuchs/minimal/builds/#{build.id}", {}, headers
response.should deliver_json_for(build, version: 'v1')
end
end

View File

@ -0,0 +1,18 @@
require 'spec_helper'
describe 'Hooks' do
before(:each) do
Scenario.default
user.permissions.create repository: repo, admin: true
end
let(:user) { User.where(login: 'svenfuchs').first }
let(:repo) { Repository.first }
let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.1+json', 'HTTP_AUTHORIZATION' => "token #{token}" } }
it 'GET /hooks' do
response = get '/hooks', {}, headers
response.should deliver_json_for(user.service_hooks, version: 'v1', type: 'hooks')
end
end

View File

@ -0,0 +1,20 @@
require 'spec_helper'
describe 'Jobs' do
let!(:jobs) {[
FactoryGirl.create(:test, :number => '3.1', :queue => 'builds.common'),
FactoryGirl.create(:test, :number => '3.2', :queue => 'builds.common')
]}
let(:job) { jobs.first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.1+json' } }
it '/jobs?queue=builds.common' do
response = get '/jobs', { queue: 'builds.common' }, headers
response.should deliver_json_for(Job.queued('builds.common'), versin: 'v1')
end
it '/jobs/:job_id' do
response = get "/jobs/#{job.id}", {}, headers
response.should deliver_json_for(job, version: 'v1')
end
end

View File

@ -0,0 +1,100 @@
require 'spec_helper'
describe 'Repos' do
before(:each) { Scenario.default }
let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.1+json' } }
it 'GET /repositories' do
response = get '/repositories', {}, headers
response.should deliver_json_for(Repository.timeline, version: 'v1')
end
it 'GET /repositories?owner_name=svenfuchs' do
response = get '/repositories', { owner_name: 'svenfuchs' }, headers
response.should deliver_json_for(Repository.by_owner_name('svenfuchs'), version: 'v1')
end
it 'GET /repositories?member=svenfuchs' do
response = get '/repositories', { member: 'svenfuchs' }, headers
response.should deliver_json_for(Repository.by_member('svenfuchs'), version: 'v1')
end
it 'GET /repositories?slug=svenfuchs/name=minimal' do
response = get '/repositories', { slug: 'svenfuchs/minimal' }, headers
response.should deliver_json_for(Repository.by_slug('svenfuchs/minimal'), version: 'v1')
end
it 'GET /repositories/1' do
response = get "repositories/#{repo.id}", {}, headers
response.should deliver_json_for(Repository.by_slug('svenfuchs/minimal').first, version: 'v1')
end
xit 'GET /svenfuchs/minimal' do
response = get '/svenfuchs/minimal', {}, headers
response.should deliver_json_for(Repository.by_slug('svenfuchs/minimal').first, version: 'v1')
end
xit 'GET /svenfuchs/minimal/cc.xml' do # TODO wat.
response = get '/svenfuchs/minimal/cc.xml'
response.should deliver_xml_for()
end
describe 'GET /svenfuchs/minimal.png' do
xit '"unknown" when the repository does not exist' do
get('/svenfuchs/does-not-exist.png').should deliver_result_image_for('unknown')
end
xit '"unknown" when it only has a build that is not finished' do
repo.builds.delete_all
Factory(:running_build, repository: repo)
get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown')
end
xit '"failing" when the last build has failed' do
repo.last_build.update_attributes!(:result => 1)
get('/svenfuchs/minimal.png').should deliver_result_image_for('failing')
end
xit '"passing" when the last build has passed' do
repo.last_build.update_attributes!(:result => 0)
get('/svenfuchs/minimal.png').should deliver_result_image_for('failing')
end
# TODO what? there's not even an image for this
xit '"stable" when there is a running build but the previous one has passed' do
Factory(:running_build, repository: repo)
repo.last_build.update_attributes!(:result => 0)
get('/svenfuchs/minimal.png').should deliver_result_image_for('stable')
end
end
describe 'GET /svenfuchs/minimal.png' do
xit '"unknown" when the repository does not exist' do
get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown')
end
xit '"unknown" when it only has a build that is not finished' do
repo.builds.delete_all
Factory(:running_build, repository: repo)
get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown')
end
xit '"failing" when the last build has failed' do
repo.last_build.update_attributes!(:result => 1)
get('/svenfuchs/minimal.png').should deliver_result_image_for('failing')
end
xit '"passing" when the last build has passed' do
repo.last_build.update_attributes!(:result => 0)
get('/svenfuchs/minimal.png').should deliver_result_image_for('passing')
end
xit '"passing" when there is a running build but the previous one has passed' do
repo.last_build.update_attributes!(:result => 0)
Factory(:running_build, :repository => repo)
get_png(repository, :branch => 'master').should serve_result_image('passing')
end
end
end

View File

@ -0,0 +1,21 @@
require 'spec_helper'
describe 'Workers' do
before(:each) do
Time.stubs(:now).returns(Time.utc(2011, 11, 11, 11, 11, 11))
@workers = [
Factory(:worker, :name => 'worker-1', :state => :working),
Factory(:worker, :name => 'worker-2', :state => :errored)
]
end
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.1+json' } }
attr_reader :workers
it 'GET /workers' do
response = get '/workers', {}, headers
response.should deliver_json_for(Worker.order(:host, :name), version: 'v1')
end
end

View File

@ -0,0 +1,13 @@
require 'spec_helper'
describe 'Branches' do
before { Scenario.default }
let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.2+json' } }
it 'GET /branches?repository_id=:repository_id' do
response = get '/branches', { repository_id: repo.id }, headers
response.should deliver_json_for(repo.last_finished_builds_by_branches, version: 'v2', type: 'branches')
end
end

View File

@ -0,0 +1,34 @@
require 'spec_helper'
describe 'Builds' do
before { Scenario.default }
let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
let(:build) { repo.builds.first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.2+json' } }
it 'GET /builds?repository_id=1' do
response = get '/builds', { repository_id: repo.id }, headers
response.should deliver_json_for(repo.builds.was_started, version: 'v2')
end
it 'GET /builds/1' do
response = get "/builds/#{build.id}", {}, headers
response.should deliver_json_for(build, version: 'v2')
end
it 'GET /builds/1?repository_id=1' do
response = get "/builds/#{build.id}", { repository_id: repo.id }, headers
response.should deliver_json_for(build, version: 'v2')
end
xit 'GET /svenfuchs/minimal/builds' do
response = get '/svenfuchs/minimal/builds', {}, headers
response.should deliver_json_for(repo.builds, version: 'v2')
end
xit 'GET /svenfuchs/minimal/builds/1' do
response = get "/svenfuchs/minimal/builds/#{build.id}", {}, headers
response.should deliver_json_for(build, version: 'v2')
end
end

View File

@ -0,0 +1,58 @@
require 'spec_helper'
require 'travis/testing/payloads'
describe 'Hooks' do
before(:each) do
Scenario.default
user.permissions.create repository: repo, admin: true
end
let(:user) { User.where(login: 'svenfuchs').first }
let(:repo) { Repository.first }
let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.2+json', 'HTTP_AUTHORIZATION' => "token #{token}" } }
it 'GET /hooks' do
response = get '/hooks', {}, headers
response.should deliver_json_for(user.service_hooks, version: 'v2', type: 'hooks')
end
describe 'PUT /hooks' do # TODO really should be /hooks/1
let(:hook) { user.service_hooks.first }
let(:target) { "repos/#{hook.owner_name}/#{hook.name}/hooks" }
let :payload do
{
:name => 'travis',
:events => ServiceHook::EVENTS,
:active => true,
:config => { :user => user.login, :token => user.tokens.first.token, :domain => 'listener.travis-ci.org' }
}
end
before(:each) do
Travis.config.stubs(:service_hook_url).returns('listener.travis-ci.org')
end
it 'creates a new hook' do
GH.stubs(:[]).returns([])
GH.expects(:post).with(target, payload)
put 'hooks', { hook: { id: hook.id, active: 'true' } }, headers
repo.reload.active?.should be_true
end
it 'updates an existing hook to be active' do
GH.stubs(:[]).returns([GH.load(PAYLOADS[:github][:hook_inactive])])
GH.expects(:post).with(target, payload)
put 'hooks', { hook: { id: hook.id, active: 'true' } }, headers
repo.reload.active?.should be_true
end
it 'updates an existing repository to be inactive' do
GH.stubs(:[]).returns([GH.load(PAYLOADS[:github][:hook_active])])
GH.expects(:post).with(target, payload.merge(:active => false))
put 'hooks', { hook: { id: hook.id, active: 'false' } }, headers
repo.reload.active?.should be_false
end
end
end

View File

@ -0,0 +1,20 @@
require 'spec_helper'
describe 'Jobs' do
let!(:jobs) {[
FactoryGirl.create(:test, :number => '3.1', :queue => 'builds.common'),
FactoryGirl.create(:test, :number => '3.2', :queue => 'builds.common')
]}
let(:job) { jobs.first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.2+json' } }
it '/jobs?queue=builds.common' do
response = get '/jobs', { queue: 'builds.common' }, headers
response.should deliver_json_for(Job.queued('builds.common'), version: 'v2')
end
it '/jobs/:job_id' do
response = get "/jobs/#{job.id}", {}, headers
response.should deliver_json_for(job, version: 'v2')
end
end

View File

@ -0,0 +1,100 @@
require 'spec_helper'
describe 'Repos' do
before(:each) { Scenario.default }
let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.2+json' } }
it 'GET /repositories' do
response = get '/repositories', {}, headers
response.should deliver_json_for(Repository.timeline, version: 'v2')
end
it 'GET /repositories?owner_name=svenfuchs' do
response = get '/repositories', { owner_name: 'svenfuchs' }, headers
response.should deliver_json_for(Repository.by_owner_name('svenfuchs'), version: 'v2')
end
it 'GET /repositories?member=svenfuchs' do
response = get '/repositories', { member: 'svenfuchs' }, headers
response.should deliver_json_for(Repository.by_member('svenfuchs'), version: 'v2')
end
it 'GET /repositories?slug=svenfuchs/name=minimal' do
response = get '/repositories', { slug: 'svenfuchs/minimal' }, headers
response.should deliver_json_for(Repository.by_slug('svenfuchs/minimal'), version: 'v2')
end
it 'GET /repositories/1' do
response = get "repositories/#{repo.id}", {}, headers
response.should deliver_json_for(Repository.by_slug('svenfuchs/minimal').first, version: 'v2')
end
xit 'GET /svenfuchs/minimal' do
response = get '/svenfuchs/minimal', {}, headers
response.should deliver_json_for(Repository.by_slug('svenfuchs/minimal').first, version: 'v2')
end
xit 'GET /svenfuchs/minimal/cc.xml' do # TODO wat.
response = get '/svenfuchs/minimal/cc.xml'
response.should deliver_xml_for()
end
describe 'GET /svenfuchs/minimal.png' do
xit '"unknown" when the repository does not exist' do
get('/svenfuchs/does-not-exist.png').should deliver_result_image_for('unknown')
end
xit '"unknown" when it only has a build that is not finished' do
repo.builds.delete_all
Factory(:running_build, repository: repo)
get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown')
end
xit '"failing" when the last build has failed' do
repo.last_build.update_attributes!(:result => 1)
get('/svenfuchs/minimal.png').should deliver_result_image_for('failing')
end
xit '"passing" when the last build has passed' do
repo.last_build.update_attributes!(:result => 0)
get('/svenfuchs/minimal.png').should deliver_result_image_for('failing')
end
# TODO what? there's not even an image for this
xit '"stable" when there is a running build but the previous one has passed' do
Factory(:running_build, repository: repo)
repo.last_build.update_attributes!(:result => 0)
get('/svenfuchs/minimal.png').should deliver_result_image_for('stable')
end
end
describe 'GET /svenfuchs/minimal.png' do
xit '"unknown" when the repository does not exist' do
get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown')
end
xit '"unknown" when it only has a build that is not finished' do
repo.builds.delete_all
Factory(:running_build, repository: repo)
get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown')
end
xit '"failing" when the last build has failed' do
repo.last_build.update_attributes!(:result => 1)
get('/svenfuchs/minimal.png').should deliver_result_image_for('failing')
end
xit '"passing" when the last build has passed' do
repo.last_build.update_attributes!(:result => 0)
get('/svenfuchs/minimal.png').should deliver_result_image_for('passing')
end
xit '"passing" when there is a running build but the previous one has passed' do
repo.last_build.update_attributes!(:result => 0)
Factory(:running_build, :repository => repo)
get_png(repository, :branch => 'master').should serve_result_image('passing')
end
end
end

View File

@ -0,0 +1,21 @@
require 'spec_helper'
describe 'Workers' do
before(:each) do
Time.stubs(:now).returns(Time.utc(2011, 11, 11, 11, 11, 11))
@workers = [
Factory(:worker, :name => 'worker-1', :state => :working),
Factory(:worker, :name => 'worker-2', :state => :errored)
]
end
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.2+json' } }
attr_reader :workers
it 'GET /workers' do
response = get '/workers', {}, headers
response.should deliver_json_for(Worker.order(:host, :name), version: 'v2')
end
end

View File

@ -1,17 +1,36 @@
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = ENV['ENV'] = 'test'
require 'rspec'
require 'travis/api/app'
require 'database_cleaner'
require 'sinatra/test_helpers'
require 'logger'
require 'gh'
require 'multi_json'
require 'travis/api/app'
require 'travis/testing/scenario'
require 'travis/testing/factories'
RSpec::Matchers.define :deliver_json_for do |resource, options = {}|
match do |response|
actual = parse(response.body)
expected = Travis::Api.data(resource, options)
failure_message_for_should do
"expected\n\n#{actual}\n\nto equal\n\n#{expected}"
end
actual == expected
end
def parse(body)
MultiJson.decode(body)
end
end
Travis.logger = Logger.new(StringIO.new)
Travis::Api::App.setup
Backports.require_relative_dir 'support'
module TestHelpers
include Sinatra::TestHelpers
@ -31,17 +50,24 @@ module TestHelpers
end
end
RSpec.configure do |config|
config.mock_framework = :mocha
config.expect_with :rspec, :stdlib
config.include TestHelpers
RSpec.configure do |c|
c.mock_framework = :mocha
c.expect_with :rspec, :stdlib
c.include TestHelpers
config.before :each do
c.before :suite do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with :transaction
end
c.before :each do
DatabaseCleaner.start
::Redis.connect(url: Travis.config.redis.url).flushdb
set_app Travis::Api::App.new
end
config.after :each do
c.after :each do
DatabaseCleaner.clean
custom_endpoints.each do |endpoint|
endpoint.superclass.direct_subclasses.delete(endpoint)
end

View File

@ -1,99 +0,0 @@
require 'factory_girl'
FactoryGirl.define do
factory :build do
repository { Repository.first || Factory(:repository) }
association :request
association :commit
end
factory :commit do
repository { Repository.first || Factory(:repository) }
commit '62aae5f70ceee39123ef'
branch 'master'
message 'the commit message'
committed_at '2011-11-11T11:11:11Z'
committer_name 'Sven Fuchs'
committer_email 'svenfuchs@artweb-design.de'
author_name 'Sven Fuchs'
author_email 'svenfuchs@artweb-design.de'
compare_url 'https://github.com/svenfuchs/minimal/compare/master...develop'
end
factory :test, :class => 'Job::Test' do
repository { Repository.first || Factory(:repository) }
commit { Factory(:commit) }
source { Factory(:build) }
log { Factory(:log) }
queue "ruby"
end
factory :log, :class => 'Artifact::Log' do
content '$ bundle install --pa'
end
factory :request do
repository { Repository.first || Factory(:repository) }
association :commit
token 'the-token'
end
factory :repository do
name 'minimal'
owner_name 'svenfuchs'
owner_email 'svenfuchs@artweb-design.de'
url { |r| "http://github.com/#{r.owner_name}/#{r.name}" }
last_duration 60
created_at { |r| Time.utc(2011, 01, 30, 5, 25) }
updated_at { |r| r.created_at + 5.minutes }
end
factory :minimal, :parent => :repository do
end
factory :enginex, :class => Repository do
name 'enginex'
owner_name 'josevalim'
last_duration 30
end
factory :running_build, :parent => :build do
repository { Factory(:repository, :name => 'running_build') }
state 'started'
end
factory :successful_build, :parent => :build do
repository { Factory(:repository, :name => 'successful_build', :last_build_result => 0) }
result 0
state 'finished'
started_at { Time.now.utc }
finished_at { Time.now.utc }
end
factory :broken_build, :parent => :build do
repository { Factory(:repository, :name => 'broken_build', :last_build_result => 1) }
result 1
state 'finished'
started_at { Time.now.utc }
finished_at { Time.now.utc }
end
factory :user do
name 'Sven Fuchs'
login 'svenfuchs'
email 'sven@fuchs.com'
tokens { [Token.new] }
end
factory :worker do
name 'worker-1'
host 'ruby-1.workers.travis-ci.org'
state :working
last_seen_at { Time.now.utc }
end
factory :ssl_key do
private_key "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDGed1uxl9szL0PVE/B6v9PDso+xRHs9e9YDB8Dm+QYFDyddud1\nn1134ZY39Dxg6zNhXDGKYilHP4E9boIuvgfSADN12eD1clogX46M4oBGgUAhtr5Q\nvGLn9TEW4IbeI+nDshMJLTLethCmB6Hwm5Ld9QnRVT6U/AztOTv9eJ/xKQIDAQAB\nAoGABQ3zcq/AnF+2bN6DzXdzmwrQYbrZEwTMXJyqaYgdzfMt/ACcMmWllrj6/1/L\n7dfvjgowBMstK/BVFUBsNk6GmmoCDHFAU+BgeyyqUxyeb63+0dIDwVYx9LHTL4dr\n9a8cVyeefqc3mqB13B9NUlS40Ij4kuK6EOGP3DZwC1FQVwECQQDtBQFqgRuNdfbV\naGIcXnuMnD4BGrnFHm0IBdLYsK4ULL85gFbhEew6DTYGYlGqX1dXbXYue8F18D8i\nzqL6HOBhAkEA1l6zvLdC2t3J9UnwpkwU0jSPX4BpHH7IkrCoGRggjwtbSxJFcCKB\nRrbPFDNAwchsa2/ldXSBrFg6Y7GlwF3lyQJAaJk+6LuVZzZZ+hAYzCA+Me15x479\n0Kn+v/2h8RL3n9ungD7NGIKKV4wg/WxCUgfFScX608S1udCObFP4xJwdwQJBALtl\nwEQqBGSmXCV0xM3rVoxH7En1TG3fm2E400pUoCnMKLugtlkHoPF7X91tzJ9aoQTu\npa2e8rkBy9FY++gFbZkCQAJ46lGEXZJqcACvLX0t/+RrvmqWMxCydLFG50kOnD8b\nVNILVyUn1lYasTs4aMYr6BRtVZoCxqV5/+rkMhb1eOM=\n-----END RSA PRIVATE KEY-----\n"
public_key "-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBAMZ53W7GX2zMvQ9UT8Hq/08Oyj7FEez171gMHwOb5BgUPJ1253WfXXfh\nljf0PGDrM2FcMYpiKUc/gT1ugi6+B9IAM3XZ4PVyWiBfjozigEaBQCG2vlC8Yuf1\nMRbght4j6cOyEwktMt62EKYHofCbkt31CdFVPpT8DO05O/14n/EpAgMBAAE=\n-----END RSA PUBLIC KEY-----\n"
end
end