11require 'json'
22require "ostruct"
3+ require 'yaml'
34
45desc 'Support for E2E tests: building XCRemoteCache-enabled xcodeproj using xcodebuild'
56namespace :e2e do
2526 'primary_branch' => GIT_BRANCH ,
2627 'mode' => 'consumer' ,
2728 'final_target' => 'XCRemoteCacheSample' ,
28- 'artifact_maximum_age' => 0
29+ 'artifact_maximum_age' => 0 ,
30+
31+ } . freeze
32+ # A list of configurations to merge with SHARED_COCOAPODS_CONFIG to run tests with
33+ CONFIGS = {
34+ 'no_swift_driver' => { } ,
35+ 'swift_driver' => {
36+ 'enable_swift_driver_integration' => true
37+ }
2938 } . freeze
3039 DEFAULT_EXPECTATIONS = {
3140 'misses' => 0 ,
3241 'hit_rate' => 100
3342 } . freeze
43+ EXCLUDED_ARCHS = 'x86_64'
3444
3545 Stats = Struct . new ( :hits , :misses , :hit_rate )
3646
4353 start_nginx
4454 configure_git
4555
46- # Run scenarios for all Podfile scenarios
47- for podfile_path in Dir . glob ( 'e2eTests/**/*.Podfile' )
48- run_cocoapods_scenario ( podfile_path )
56+ for config_name , custom_config in CONFIGS
57+ config = SHARED_COCOAPODS_CONFIG . merge ( custom_config )
58+ puts "Running E2E tests for config: #{ config_name } "
59+
60+ # Run scenarios for all Podfile scenarios
61+ for podfile_path in Dir . glob ( 'e2eTests/**/*.Podfile' )
62+ run_cocoapods_scenario ( config , podfile_path )
63+ end
4964 end
5065 # Revert all side effects
5166 clean
5671 clean_server
5772 start_nginx
5873 configure_git
74+ CONFIGS . each do |config_name , config |
75+ puts "Running Standalone tests for config: #{ config_name } "
76+ run_standalone_scenario ( config , config_name )
77+ end
78+ end
79+
80+ def self . run_standalone_scenario ( config , config_name )
5981 # Prepare binaries for the standalone mode
6082 prepare_for_standalone ( E2E_STANDALONE_SAMPLE_DIR )
6183
6284 puts 'Building standalone producer...'
6385 ####### Producer #########
86+ clean_git
87+
6488 Dir . chdir ( E2E_STANDALONE_SAMPLE_DIR ) do
65- clean_git
89+ system 'git checkout -f .'
90+ # Include the config in the "shared" configuration that is commited-in to '.rcinfo'
91+ rcinfo_path = '.rcinfo'
92+ rcinfo = YAML . load ( File . read ( rcinfo_path ) ) . merge ( config )
93+ File . open ( rcinfo_path , 'w' ) { |f | f . write rcinfo . to_yaml }
94+
6695 # Run integrate the project
6796 system ( "pwd" )
6897 system ( "#{ XCRC_BINARIES } /xcprepare integrate --input StandaloneApp.xcodeproj --mode producer --final-producer-target StandaloneApp --configurations-exclude #{ CONFIGURATIONS_EXCLUDE } " )
76105
77106 ####### Consumer #########
78107 # new dir to emulate different srcroot
79- consumer_srcroot = "#{ E2E_STANDALONE_SAMPLE_DIR } _consumer "
108+ consumer_srcroot = "#{ E2E_STANDALONE_SAMPLE_DIR } _consumer_ #{ config_name } "
80109 system ( "mv #{ E2E_STANDALONE_SAMPLE_DIR } #{ consumer_srcroot } " )
81- at_exit { puts ( "reverting #{ E2E_STANDALONE_SAMPLE_DIR } " ) ; system ( "mv #{ consumer_srcroot } #{ E2E_STANDALONE_SAMPLE_DIR } " ) }
82-
83- prepare_for_standalone ( consumer_srcroot )
84- Dir . chdir ( consumer_srcroot ) do
85- system ( "#{ XCRC_BINARIES } /xcprepare integrate --input StandaloneApp.xcodeproj --mode consumer --final-producer-target StandaloneApp --consumer-eligible-configurations #{ CONFIGURATION } --configurations-exclude #{ CONFIGURATIONS_EXCLUDE } " )
86- build_project ( nil , "StandaloneApp.xcodeproj" , 'WatchExtension' , 'watch' , 'watchOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer" } )
87- build_project ( nil , "StandaloneApp.xcodeproj" , 'StandaloneApp' , 'iphone' , 'iOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer" } )
88- valide_hit_rate ( OpenStruct . new ( DEFAULT_EXPECTATIONS ) )
89-
90- puts 'Building standalone consumer with local change...'
91- # Extra: validate local compilation of the Standalone ObjC code
92- system ( "echo '' >> StandaloneApp/StandaloneObjc.m" )
93- build_project ( nil , "StandaloneApp.xcodeproj" , 'WatchExtension' , 'watch' , 'watchOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer_local" } )
94- build_project ( nil , "StandaloneApp.xcodeproj" , 'StandaloneApp' , 'iphone' , 'iOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer_local" } )
110+ begin
111+ prepare_for_standalone ( consumer_srcroot )
112+ Dir . chdir ( consumer_srcroot ) do
113+ system ( "#{ XCRC_BINARIES } /xcprepare integrate --input StandaloneApp.xcodeproj --mode consumer --final-producer-target StandaloneApp --consumer-eligible-configurations #{ CONFIGURATION } --configurations-exclude #{ CONFIGURATIONS_EXCLUDE } " )
114+ build_project ( nil , "StandaloneApp.xcodeproj" , 'WatchExtension' , 'watch' , 'watchOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer_#{ config_name } " } )
115+ build_project ( nil , "StandaloneApp.xcodeproj" , 'StandaloneApp' , 'iphone' , 'iOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer_#{ config_name } " } )
116+ valide_hit_rate ( OpenStruct . new ( DEFAULT_EXPECTATIONS ) )
117+
118+ puts 'Building standalone consumer with local change...'
119+ # Extra: validate local compilation of the Standalone ObjC code
120+ system ( "echo '' >> StandaloneApp/StandaloneObjc.m" )
121+ build_project ( nil , "StandaloneApp.xcodeproj" , 'WatchExtension' , 'watch' , 'watchOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer_local_#{ config_name } " } )
122+ build_project ( nil , "StandaloneApp.xcodeproj" , 'StandaloneApp' , 'iphone' , 'iOS' , CONFIGURATION , { 'derivedDataPath' => "#{ DERIVED_DATA_PATH } _consumer_local_#{ config_name } " } )
123+ end
124+ ensure
125+ puts ( "reverting #{ E2E_STANDALONE_SAMPLE_DIR } " )
126+ system ( "mv #{ consumer_srcroot } #{ E2E_STANDALONE_SAMPLE_DIR } " )
95127 end
96128
97129 # Revert all side effects
@@ -153,9 +185,9 @@ def self.clean
153185 end
154186
155187 # xcremotecache configuration to add to Podfile
156- def self . cocoapods_configuration_string ( extra_configs = { } )
188+ def self . cocoapods_configuration_string ( config , extra_configs = { } )
157189 configuration_lines = [ 'xcremotecache({' ]
158- all_properties = SHARED_COCOAPODS_CONFIG . merge ( extra_configs )
190+ all_properties = config . merge ( extra_configs )
159191 config_lines = all_properties . map { |key , value | " \" #{ key } \" => #{ value . inspect } ," }
160192 configuration_lines . push ( *config_lines )
161193 configuration_lines << '})'
@@ -182,7 +214,7 @@ def self.build_project(workspace, project, scheme, sdk = 'iphone', platform = 'i
182214 'derivedDataPath' => DERIVED_DATA_PATH ,
183215 } . merge ( extra_args ) . compact
184216 xcodebuild_vars = {
185- 'EXCLUDED_ARCHS' => 'arm64'
217+ 'EXCLUDED_ARCHS' => EXCLUDED_ARCHS
186218 }
187219 args = [ 'set -o pipefail;' , 'xcodebuild' ]
188220 args . push ( *xcodebuild_args . map { |k , v | "-#{ k } '#{ v } '" } )
@@ -227,12 +259,12 @@ def self.valide_hit_rate(expectations)
227259 puts ( "Hit rate: #{ status . hit_rate } % (#{ status . hits } /#{ all_targets } )" )
228260 end
229261
230- def self . run_cocoapods_scenario ( template_path )
262+ def self . run_cocoapods_scenario ( config , template_path )
231263 # Optional file, which adds extra cocoapods configs to a template
232264 template_config_path = "#{ template_path } .config"
233265 extra_config = File . exist? ( template_config_path ) ? JSON . load ( File . read ( template_config_path ) ) : { }
234- producer_configuration = cocoapods_configuration_string ( { 'mode' => 'producer' } . merge ( extra_config ) )
235- consumer_configuration = cocoapods_configuration_string ( extra_config )
266+ producer_configuration = cocoapods_configuration_string ( config , { 'mode' => 'producer' } . merge ( extra_config ) )
267+ consumer_configuration = cocoapods_configuration_string ( config , extra_config )
236268 expectations = build_expectations ( template_path )
237269
238270 puts ( "****** Scenario: #{ template_path } " )
0 commit comments