Extract to a separate file
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# encoding: utf-8
|
||||
require 'json'
|
||||
require_relative 'tasks/e2e'
|
||||
|
||||
################################
|
||||
# Rake configuration
|
||||
@@ -78,112 +79,11 @@ task :test do
|
||||
spm_test()
|
||||
end
|
||||
|
||||
desc 'run E2E tests with CocoaPods plugin'
|
||||
desc 'build and run E2E tests'
|
||||
task :e2e => [:build, :e2e_only]
|
||||
|
||||
desc 'run E2E tests without building the XCRemoteCache binary'
|
||||
task :e2e_only do
|
||||
# Build a plugin
|
||||
cocoapods_dir = 'cocoapods-plugin'
|
||||
Dir.chdir(cocoapods_dir) do
|
||||
gemspec_path = "cocoapods-xcremotecache.gemspec"
|
||||
gemfile_path = "cocoapods-xcremotecache.gem"
|
||||
system("gem build #{gemspec_path} -o #{gemfile_path}")
|
||||
system("gem install #{gemfile_path}")
|
||||
end
|
||||
|
||||
# Start nginx server
|
||||
system('nginx -c $PWD/e2eTests/nginx/nginx.conf')
|
||||
Signal.trap(0, proc { system('nginx -s stop') })
|
||||
|
||||
current_branch = 'e2e-test-branch'
|
||||
producer_configuration = %{xcremotecache({
|
||||
'cache_addresses' => ['http://localhost:8080/cache/pods'],
|
||||
'primary_repo' => '.',
|
||||
'primary_branch' => '#{current_branch}',
|
||||
'mode' => 'producer',
|
||||
'final_target' => 'XCRemoteCacheSample',
|
||||
'artifact_maximum_age' => 0
|
||||
})}
|
||||
consumer_configuration = %{xcremotecache({
|
||||
'cache_addresses' => ['http://localhost:8080/cache/pods'],
|
||||
'primary_repo' => '.',
|
||||
'primary_branch' => '#{current_branch}',
|
||||
'mode' => 'consumer',
|
||||
'final_target' => 'XCRemoteCacheSample',
|
||||
'artifact_maximum_age' => 0
|
||||
})}
|
||||
# Configure remote
|
||||
system("git checkout -b #{current_branch}")
|
||||
system('git remote add self . && git fetch self')
|
||||
|
||||
log_name = "xcodebuild.log"
|
||||
# initalize Pods
|
||||
for podfile_path in Dir.glob('e2eTests/**/*.Podfile')
|
||||
p "****** Scenario: #{podfile_path}"
|
||||
system('rm -rf /tmp/cache')
|
||||
# Revert any local changes
|
||||
system('git clean -xdf e2eTests/XCRemoteCacheSample')
|
||||
# Link prebuild binaries to the Project
|
||||
system('ln -s $(pwd)/releases e2eTests/XCRemoteCacheSample/XCRC')
|
||||
|
||||
|
||||
# Create producer Podfile
|
||||
File.open('e2eTests/XCRemoteCacheSample/Podfile', 'w') do |f|
|
||||
# Copy podfile
|
||||
File.foreach(podfile_path) { |line| f.puts line }
|
||||
|
||||
f.write(producer_configuration)
|
||||
end
|
||||
|
||||
Dir.chdir('e2eTests/XCRemoteCacheSample') do
|
||||
system('pod install')
|
||||
p "Building producer ..."
|
||||
system("xcodebuild -workspace 'XCRemoteCacheSample.xcworkspace' -scheme 'XCRemoteCacheSample' -configuration 'Debug' -sdk 'iphonesimulator' -destination 'generic/platform=iOS Simulator' -derivedDataPath ./DerivedData EXCLUDED_ARCHS='arm64 i386' clean build > #{log_name}")
|
||||
|
||||
# reset stats
|
||||
system('XCRC/xcprepare stats --reset --format json')
|
||||
# clean DerivedData
|
||||
system('rm -rf ./DerivedData')
|
||||
end
|
||||
|
||||
|
||||
# Create consumer Podfile
|
||||
File.open('e2eTests/XCRemoteCacheSample/Podfile', 'w') do |f|
|
||||
# Copy podfile
|
||||
File.foreach(podfile_path) { |line| f.puts line; p }
|
||||
|
||||
f.write(consumer_configuration)
|
||||
end
|
||||
|
||||
Dir.chdir('e2eTests/XCRemoteCacheSample') do
|
||||
system('pod install')
|
||||
p "Building consumer ..."
|
||||
system("xcodebuild -workspace 'XCRemoteCacheSample.xcworkspace' -scheme 'XCRemoteCacheSample' -configuration 'Debug' -sdk 'iphonesimulator' -destination 'generic/platform=iOS Simulator' -derivedDataPath ./DerivedData EXCLUDED_ARCHS='arm64 i386' clean build > #{log_name}")
|
||||
|
||||
# validate 100% hit rate
|
||||
stats_json_string = JSON.parse(`XCRC/xcprepare stats --format json`)
|
||||
misses = stats_json_string.fetch('miss_count', 0)
|
||||
hits = stats_json_string.fetch('hit_count', 0)
|
||||
all_targets = misses + hits
|
||||
raise "Failure: XCRemoteCache is disabled" if all_targets == 0
|
||||
hit_rate = hits * 100 / all_targets
|
||||
raise "Failure: Hit rate is only #{hit_rate}%" if misses != 0
|
||||
p "hit rate: #{hit_rate}% (#{hits}/#{all_targets})"
|
||||
|
||||
# clean DerivedData
|
||||
system('rm -rf ./DerivedData')
|
||||
end
|
||||
|
||||
# Destroy a cache
|
||||
system('rm -rf /tmp/cache')
|
||||
end
|
||||
|
||||
# Revert remote
|
||||
system('git remote remove self')
|
||||
|
||||
end
|
||||
|
||||
task :e2e_only => ['e2e:run']
|
||||
|
||||
################################
|
||||
# Helper functions
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
require 'json'
|
||||
|
||||
desc 'Support for E2E tests: building XCRemoteCache-enabled xcodeproj using xcodebuild'
|
||||
namespace :e2e do
|
||||
COCOAPODS_DIR = 'cocoapods-plugin'
|
||||
COCOAPODS_GEMSPEC_FILENAME = "cocoapods-xcremotecache.gemspec"
|
||||
E2E_COCOAPODS_SAMPLE_DIR = 'e2eTests/XCRemoteCacheSample'
|
||||
GIT_REMOTE_NAME = 'self'
|
||||
# Location of the remote address that points to itself
|
||||
GIT_REMOTE_ADDRESS = '.'
|
||||
GIT_BRANCH = 'e2e-test-branch'
|
||||
LOG_NAME = "xcodebuild.log"
|
||||
DERIVED_DATA_PATH = './DerivedData'
|
||||
NGINX_ROOT_DIR = '/tmp/cache'
|
||||
XCRC_BINARIES = 'XCRC'
|
||||
SHARED_COCOAPODS_CONFIG = {
|
||||
'cache_addresses' => ['http://localhost:8080/cache/pods'],
|
||||
'primary_repo' => GIT_REMOTE_ADDRESS,
|
||||
'primary_branch' => GIT_BRANCH,
|
||||
'mode' => 'consumer',
|
||||
'final_target' => 'XCRemoteCacheSample',
|
||||
'artifact_maximum_age' => 0
|
||||
}
|
||||
|
||||
Stats = Struct.new(:hits, :misses, :hit_rate)
|
||||
|
||||
# run E2E tests
|
||||
task :run => [:run_cocoapods]
|
||||
|
||||
# run E2E tests for CocoaPods-powered projects
|
||||
task :run_cocoapods do
|
||||
install_cocoapods_plugin
|
||||
start_nginx
|
||||
configure_git
|
||||
|
||||
# Run scenarios for all Podfile scenarios
|
||||
for podfile_path in Dir.glob('e2eTests/**/*.Podfile')
|
||||
run_cocoapods_scenario(podfile_path)
|
||||
end
|
||||
# Revert all side effects
|
||||
clean
|
||||
end
|
||||
|
||||
# Build and install a plugin
|
||||
def self.install_cocoapods_plugin
|
||||
Dir.chdir(COCOAPODS_DIR) do
|
||||
gemfile_path = "cocoapods-xcremotecache.gem"
|
||||
system("gem build #{COCOAPODS_GEMSPEC_FILENAME} -o #{gemfile_path}")
|
||||
system("gem install #{gemfile_path}")
|
||||
end
|
||||
end
|
||||
|
||||
def self.start_nginx
|
||||
# Start nginx server
|
||||
system('nginx -c $PWD/e2eTests/nginx/nginx.conf')
|
||||
puts('starting nginx')
|
||||
# Call cleanup on exit
|
||||
at_exit { puts('resetting ngingx'); system('nginx -s stop') }
|
||||
end
|
||||
|
||||
# Create a new branch out of a current commit and
|
||||
# add remote that points to itself
|
||||
def self.configure_git
|
||||
system("git checkout -B #{GIT_BRANCH}")
|
||||
system("git remote add #{GIT_REMOTE_NAME} #{GIT_REMOTE_ADDRESS} && git fetch -q #{GIT_REMOTE_NAME}")
|
||||
# Revert new remote on exit
|
||||
at_exit { system("git remote remove #{GIT_REMOTE_NAME}")}
|
||||
end
|
||||
|
||||
def self.pre_producer_setup
|
||||
clean_git
|
||||
clean_server
|
||||
# Link prebuilt binaries to the Project
|
||||
system("ln -s $(pwd)/releases #{E2E_COCOAPODS_SAMPLE_DIR}/#{XCRC_BINARIES}")
|
||||
end
|
||||
|
||||
def self.pre_consumer_setup
|
||||
clean_git
|
||||
# Link prebuilt binaries to the Project
|
||||
system("ln -s $(pwd)/releases #{E2E_COCOAPODS_SAMPLE_DIR}/#{XCRC_BINARIES}")
|
||||
end
|
||||
|
||||
def self.clean_server
|
||||
system("rm -rf #{NGINX_ROOT_DIR}")
|
||||
end
|
||||
|
||||
# Revert any local changes in the test project
|
||||
def self.clean_git
|
||||
system("git clean -xdf #{E2E_COCOAPODS_SAMPLE_DIR}")
|
||||
end
|
||||
|
||||
# Cleans all extra locations that a test creates
|
||||
def self.clean
|
||||
clean_git
|
||||
clean_server
|
||||
end
|
||||
|
||||
# xcremotecache configuration to add to Podfile
|
||||
def self.cocoapods_configuration_string(extra_configs = {})
|
||||
configuration_lines = ['xcremotecache({']
|
||||
all_properties = SHARED_COCOAPODS_CONFIG.merge(extra_configs)
|
||||
config_lines = all_properties.map {|key, value| " \"#{key}\" => #{value.inspect},"}
|
||||
configuration_lines.push(*config_lines)
|
||||
configuration_lines << '})'
|
||||
configuration_lines.join("\n")
|
||||
end
|
||||
|
||||
def self.dump_podfile(config, source)
|
||||
# Create producer Podfile
|
||||
File.open("#{E2E_COCOAPODS_SAMPLE_DIR}/Podfile", 'w') do |f|
|
||||
# Copy podfile template
|
||||
File.foreach(source) { |line| f.puts line }
|
||||
f.write(config)
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_project
|
||||
system('pod install')
|
||||
xcodebuild_args = {
|
||||
'workspace' => 'XCRemoteCacheSample.xcworkspace',
|
||||
'scheme' => 'XCRemoteCacheSample',
|
||||
'configuration' => 'Debug',
|
||||
'sdk' => 'iphonesimulator',
|
||||
'destination' => 'generic/platform=iOS Simulator',
|
||||
'derivedDataPath' => DERIVED_DATA_PATH,
|
||||
}
|
||||
xcodebuild_vars = {
|
||||
'EXCLUDED_ARCHS' => 'arm64 i386'
|
||||
}
|
||||
args = ['xcodebuild']
|
||||
args.push(*xcodebuild_args.map {|k,v| "-#{k} '#{v}'"})
|
||||
args.push(*xcodebuild_vars.map {|k,v| "#{k}='#{v}'"})
|
||||
args.push('clean build')
|
||||
args.push("> #{LOG_NAME}")
|
||||
puts 'Building a project with xcodebuild...'
|
||||
system(args.join(' '))
|
||||
unless $?.success?
|
||||
system("tail #{LOG_NAME}")
|
||||
raise "xcodebuild failed."
|
||||
end
|
||||
end
|
||||
|
||||
def self.read_stats
|
||||
stats_json_string = JSON.parse(`#{XCRC_BINARIES}/xcprepare stats --format json`)
|
||||
misses = stats_json_string.fetch('miss_count', 0)
|
||||
hits = stats_json_string.fetch('hit_count', 0)
|
||||
all_targets = misses + hits
|
||||
raise "Failure: No XCRemoteCache targets invoked" if all_targets == 0
|
||||
hit_rate = hits * 100 / all_targets
|
||||
Stats.new(hits, misses, hit_rate)
|
||||
end
|
||||
|
||||
# validate 100% hit rate
|
||||
def self.valide_hit_rate
|
||||
status = read_stats()
|
||||
raise "Failure: Hit rate is only #{status.hit_rate}% (#{status.hits}/#{status.all_targets})" if status.misses > 0
|
||||
all_targets = status.misses + status.hits
|
||||
puts("Hit rate: #{status.hit_rate}% (#{status.hits}/#{all_targets})")
|
||||
end
|
||||
|
||||
def self.run_cocoapods_scenario(template_path)
|
||||
producer_configuration = cocoapods_configuration_string({'mode' => 'producer'})
|
||||
consumer_configuration = cocoapods_configuration_string()
|
||||
|
||||
puts("****** Scenario: #{template_path}")
|
||||
|
||||
# Run producer build
|
||||
pre_producer_setup
|
||||
dump_podfile(producer_configuration, template_path)
|
||||
puts('Building producer ...')
|
||||
Dir.chdir(E2E_COCOAPODS_SAMPLE_DIR) do
|
||||
build_project
|
||||
# reset XCRemoteCache stats
|
||||
system("#{XCRC_BINARIES}/xcprepare stats --reset --format json")
|
||||
end
|
||||
|
||||
# Run consumer build
|
||||
pre_consumer_setup
|
||||
dump_podfile(consumer_configuration, template_path)
|
||||
puts('Building consumer ...')
|
||||
Dir.chdir(E2E_COCOAPODS_SAMPLE_DIR) do
|
||||
build_project
|
||||
valide_hit_rate
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user