From 464391a97c251de08261f035e9e1a8fdaf79f97c Mon Sep 17 00:00:00 2001 From: Bo Anderson Date: Wed, 6 Mar 2024 04:08:42 +0000 Subject: [PATCH] cmd/lib/ci_matrix: always test both real arm and real intel --- cmd/lib/ci_matrix.rb | 59 ++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/cmd/lib/ci_matrix.rb b/cmd/lib/ci_matrix.rb index 1c013b8387..82be903207 100644 --- a/cmd/lib/ci_matrix.rb +++ b/cmd/lib/ci_matrix.rb @@ -7,12 +7,16 @@ require_relative "changed_files" module CiMatrix MAX_JOBS = 256 - RUNNERS = { + # Weight for each arch must add up to 1.0. + INTEL_RUNNERS = { { symbol: :big_sur, name: "macos-11", arch: :intel } => 0.0, { symbol: :monterey, name: "macos-12", arch: :intel } => 0.0, { symbol: :ventura, name: "macos-13", arch: :intel } => 1.0, - { symbol: :sonoma, name: "macos-14", arch: :arm } => 0.0, }.freeze + ARM_RUNNERS = { + { symbol: :sonoma, name: "macos-14", arch: :arm } => 1.0, + }.freeze + RUNNERS = INTEL_RUNNERS.merge(ARM_RUNNERS).freeze # This string uses regex syntax and is intended to be interpolated into # `Regexp` literals, so the backslashes must be escaped to be preserved. @@ -59,12 +63,30 @@ module CiMatrix ) end end - return filtered_runners unless filtered_runners.empty? + filtered_runners = RUNNERS.dup if filtered_runners.empty? + + archs = architectures(cask_content:) + filtered_runners.select! do |runner, _| + archs.include?(runner.fetch(:arch)) + end RUNNERS end - def self.random_runner(avalible_runners = RUNNERS) + def self.architectures(cask_content:) + case cask_content + when /depends_on\s+arch:\s+:arm64/ + [:arm] + when /depends_on\s+arch:\s+:x86_64/ + [:intel] + when /\barch\b/, /\bon_(arm|intel)\b/ + [:arm, :intel] + else + RUNNERS.keys.map { |r| r.fetch(:arch) }.uniq.sort + end + end + + def self.random_runner(avalible_runners = INTEL_RUNNERS) avalible_runners.max_by { |(_, weight)| rand ** (1.0 / weight) } .first end @@ -82,23 +104,14 @@ module CiMatrix if filtered_macos_found # If the cask varies on a MacOS version, test it on every possible macOS version. - filtered_runners.keys + [filtered_runners.keys, true] else - # Otherwise, select a runner based on weighted random sample. - [random_runner(filtered_runners)] - end - end - - def self.architectures(cask_content:) - case cask_content - when /depends_on\s+arch:\s+:arm64/ - [:arm] - when /depends_on\s+arch:\s+:x86_64/ - [:intel] - when /\barch\b/, /\bon_(arm|intel)\b/ - [:arm, :intel] - else - RUNNERS.keys.map { |r| r.fetch(:arch) }.uniq.sort + # Otherwise, select a runner from each architecture based on weighted random sample. + grouped_runners = filtered_runners.group_by { |runner, _| runner.fetch(:arch) } + selected_runners = grouped_runners.map do |_, runners| + random_runner(runners) + end + [selected_runners, false] end end @@ -166,8 +179,12 @@ module CiMatrix cask_content = path.read - runners(cask_content: cask_content).product(architectures(cask_content: cask_content)).map do |runner, arch| + runners, multi_os = runners(cask_content: cask_content) + runners.product(architectures(cask_content: cask_content)).map do |runner, arch| native_runner_arch = arch == runner.fetch(:arch) + # If it's just a single OS test then we can just use the two real arch runners. + next if !native_runner_arch && !multi_os + arch_args = native_runner_arch ? [] : ["--arch=#{arch}"] { name: "test #{cask_token} (#{runner.fetch(:name)}, #{arch})",