From dbdd762a137e5d86ab7db2aa92a47dc04a80b7be Mon Sep 17 00:00:00 2001 From: John McCrae Date: Tue, 7 Oct 2025 21:25:55 +0000 Subject: [PATCH 1/2] updating ActiveSupport and tests which were failing with licensing changes? Signed-off-by: John McCrae --- components/ruby/Gemfile.lock | 105 +++++++++++++----- components/ruby/chef-licensing.gemspec | 2 +- .../license_key_fetcher/file.rb | 30 +++-- components/ruby/spec/config_spec.rb | 1 + components/ruby/spec/spec_helper.rb | 81 +++++++++++++- 5 files changed, 185 insertions(+), 34 deletions(-) diff --git a/components/ruby/Gemfile.lock b/components/ruby/Gemfile.lock index b567780e7..dcaa9d9c0 100644 --- a/components/ruby/Gemfile.lock +++ b/components/ruby/Gemfile.lock @@ -1,60 +1,110 @@ PATH remote: . specs: - chef-licensing (0.7.5) - activesupport (~> 7.0, < 7.1) + chef-licensing (1.2.0) + activesupport (> 7.1.3.2, < 7.2) chef-config (>= 15) - faraday (>= 1, < 3) + faraday (>= 1, < 2) faraday-http-cache + mixlib-log (~> 3.0) + ostruct (~> 0.1.0) tty-prompt (~> 0.23) tty-spinner (~> 0.9.3) GEM remote: https://rubygems.org/ specs: - activesupport (7.0.8) + activesupport (7.1.5.2) + base64 + benchmark (>= 0.3) + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) tzinfo (~> 2.0) - addressable (2.8.5) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) - base64 (0.1.1) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.3.0) byebug (11.1.3) - chef-config (18.3.0) + chef-config (18.8.11) addressable - chef-utils (= 18.3.0) + chef-utils (= 18.8.11) fuzzyurl mixlib-config (>= 2.2.12, < 4.0) mixlib-shellout (>= 2.0, < 4.0) tomlrb (~> 1.2) - chef-utils (18.3.0) + chef-utils (18.8.11) concurrent-ruby chefstyle (2.2.2) rubocop (= 1.25.1) coderay (1.1.3) - concurrent-ruby (1.2.2) - crack (0.4.5) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) + crack (1.0.0) + bigdecimal rexml diff-lcs (1.5.0) - faraday (2.7.11) - base64 - faraday-net_http (>= 2.0, < 3.1) + drb (2.2.3) + faraday (1.10.4) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) ruby2_keywords (>= 0.0.4) - faraday-http-cache (2.5.0) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.1) + faraday-excon (1.1.0) + faraday-http-cache (2.5.1) faraday (>= 0.8) - faraday-net_http (3.0.2) + faraday-httpclient (1.0.1) + faraday-multipart (1.1.1) + multipart-post (~> 2.0) + faraday-net_http (1.0.2) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x64-mingw-ucrt) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi-win32-extensions (1.0.4) + ffi fuzzyurl (0.9.0) - hashdiff (1.0.1) - i18n (1.14.1) + hashdiff (1.2.1) + i18n (1.14.7) concurrent-ruby (~> 1.0) + logger (1.7.0) method_source (1.0.0) - minitest (5.20.0) + minitest (5.25.5) mixlib-config (3.0.27) tomlrb - mixlib-shellout (3.2.7) + mixlib-log (3.2.3) + ffi (>= 1.15.5) + mixlib-shellout (3.3.9) + chef-utils + mixlib-shellout (3.3.9-x64-mingw-ucrt) chef-utils + ffi-win32-extensions (~> 1.0.3) + win32-process (~> 0.9) + wmi-lite (~> 1.0) + multipart-post (2.4.1) + mutex_m (0.3.0) + ostruct (0.1.0) parallel (1.22.1) parser (3.1.2.1) ast (~> 2.4.1) @@ -63,7 +113,7 @@ GEM pry (0.14.1) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.3) + public_suffix (6.0.2) rainbow (3.1.1) rake (13.0.6) regexp_parser (2.6.0) @@ -95,6 +145,7 @@ GEM parser (>= 3.1.1.0) ruby-progressbar (1.11.0) ruby2_keywords (0.0.5) + securerandom (0.4.1) strscan (3.1.0) tomlrb (1.3.0) tty-color (0.6.0) @@ -106,20 +157,24 @@ GEM tty-cursor (~> 0.7) tty-screen (~> 0.8) wisper (~> 2.0) - tty-screen (0.8.1) + tty-screen (0.8.2) tty-spinner (0.9.3) tty-cursor (~> 0.7) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.3.0) - webmock (3.18.1) + webmock (3.25.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) + win32-process (0.10.0) + ffi (>= 1.0.0) wisper (2.0.1) + wmi-lite (1.0.7) PLATFORMS arm64-darwin-22 + x64-mingw-ucrt x86_64-darwin-19 x86_64-darwin-21 x86_64-linux @@ -131,7 +186,7 @@ DEPENDENCIES pry rake (~> 13.0, >= 13.0.6) rspec (~> 3.11) - webmock (~> 3.18, >= 3.18.1) + webmock (~> 3.25, >= 3.25.1) BUNDLED WITH 2.3.18 diff --git a/components/ruby/chef-licensing.gemspec b/components/ruby/chef-licensing.gemspec index 322895faa..e7a0336a0 100644 --- a/components/ruby/chef-licensing.gemspec +++ b/components/ruby/chef-licensing.gemspec @@ -30,7 +30,7 @@ Gem::Specification.new do |spec| spec.add_dependency "tty-prompt", "~> 0.23" spec.add_dependency "faraday", ">= 1", "< 2" spec.add_dependency "faraday-http-cache" - spec.add_dependency "activesupport", "~> 7.2", ">= 7.2.2.1" + spec.add_dependency "activesupport", "> 7.1.3.2", "< 7.2" spec.add_dependency "tty-spinner", "~> 0.9.3" spec.add_dependency "mixlib-log", "~> 3.0" diff --git a/components/ruby/lib/chef-licensing/license_key_fetcher/file.rb b/components/ruby/lib/chef-licensing/license_key_fetcher/file.rb index 1487d33da..d89c38c70 100644 --- a/components/ruby/lib/chef-licensing/license_key_fetcher/file.rb +++ b/components/ruby/lib/chef-licensing/license_key_fetcher/file.rb @@ -136,19 +136,35 @@ def fetch_or_persist_url(license_server_url_from_config, license_server_url_from @contents = load_license_file(license_key_file_path) - # Three possible cases: - # 1. If contents is nil or an error occurred while loading, load basic license data with the latest structure. - # 2. If contents is not nil and valid, but the license server URL in contents is different from the system's, - # update the license server URL in contents and licenses.yaml file. - # 3. If contents is valid and no update is needed, return the existing license server URL. + # Allow developers to opt-out of using system-provided license server URLs + # (for example CI/developer envs that set CHEF_LICENSE_SERVER). When the + # env var CHEF_LICENSE_IGNORE_SYSTEM_LICENSE_SERVER is set we will not + # consider the system value for persisting into the licenses.yaml file. + if ENV["CHEF_LICENSE_IGNORE_SYSTEM_LICENSE_SERVER"] + logger.debug("Ignoring system-provided license server URL due to CHEF_LICENSE_IGNORE_SYSTEM_LICENSE_SERVER") if logger + license_server_url_from_system = nil + end + + # Decide when to update the license_server_url persisted in licenses.yaml. + # Priority (highest -> lowest): + # 1. Explicit config/CLI value (license_server_url_from_config) + # 2. Existing value in the file (do not let system/env override it) + # 3. System/env value (license_server_url_from_system) only if file is absent # Handle error cases first - when file loading failed or contents is nil if @contents.is_a?(StandardError) || @contents.nil? + # No existing file or failed to load: prefer system value but fall back to config url = license_server_url_from_system || license_server_url_from_config load_basic_license_data_to_contents(url, []) - elsif @contents && license_server_url_from_system && license_server_url_from_system != @contents[:license_server_url] + elsif license_server_url_from_config && license_server_url_from_config != @contents[:license_server_url] + # An explicit config/arg should overwrite the persisted value + @contents[:license_server_url] = license_server_url_from_config + elsif license_server_url_from_system && license_server_url_from_system != @contents[:license_server_url] + # If a system-provided value (ENV/CLI) is present and differs from the + # persisted value, treat it as an explicit override unless the caller + # has intentionally set CHEF_LICENSE_IGNORE_SYSTEM_LICENSE_SERVER. @contents[:license_server_url] = license_server_url_from_system else - # Nothing to change in the file + # Nothing to change in the file: return the existing persisted value @license_server_url = @contents[:license_server_url] return @license_server_url end diff --git a/components/ruby/spec/config_spec.rb b/components/ruby/spec/config_spec.rb index e11a522be..50ee481ef 100644 --- a/components/ruby/spec/config_spec.rb +++ b/components/ruby/spec/config_spec.rb @@ -1,3 +1,4 @@ +require "spec_helper" require "chef-licensing/config" require "logger" require "stringio" diff --git a/components/ruby/spec/spec_helper.rb b/components/ruby/spec/spec_helper.rb index 8808dc28c..21796e3c2 100644 --- a/components/ruby/spec/spec_helper.rb +++ b/components/ruby/spec/spec_helper.rb @@ -1,13 +1,92 @@ require "bundler/setup" -require "chef-licensing" +require "tmpdir" +require "fileutils" + +# Create a suite-level temporary HOME early so any code executed at +# require-time that consults the user's HOME doesn't accidentally pick up +# a real developer/CI HOME. We use a lightweight suite-level HOME to +# avoid unnecessary temp-dir churn during startup. Some specs still need +# a clean HOME per-example (they create or expect files under HOME); to +# support those we provide a per-example around hook below which swaps +# in a fresh HOME for the duration of the example. +TMP_TEST_HOME = Dir.mktmpdir("chef_licensing_spec_home") +ENV["HOME"] = TMP_TEST_HOME +# On Windows set USERPROFILE as well for early initialization +ENV["USERPROFILE"] = TMP_TEST_HOME if Gem.win_platform? + +# Explicitly set the license server used by tests to a stable, test-only +# URL. This prevents tests from accidentally using a developer/CI +# provided value or reading an on-disk persisted value that points at a +# production server. Keep this deterministic to make tests hermetic. +ENV["CHEF_LICENSE_SERVER"] = "https://custom-licensing-server.com/License" +ENV["LICENSE_SERVER"] = "https://custom-licensing-server.com/License" + +# Clear any real license key from the environment so tests don't pick up +# developer/CI credentials by accident. This avoids flaky tests where a +# real key would change behavior or reach out to real endpoints. +ENV.delete("CHEF_LICENSE_KEY") + +# Require WebMock before requiring the library so that any HTTP client +# initialization that runs during require-time (for example middleware +# setup that probes a host) is intercepted. Requiring WebMock early is +# the simplest way to guarantee no accidental real HTTP connections +# happen while the test harness initializes. require "webmock/rspec" +require "chef-licensing" RSpec.configure do |config| + # We set a suite-level TMP_TEST_HOME above to keep startup fast and to + # prevent require-time code from touching a real HOME. Some specs, + # however, depend on a clean HOME per-example to test file persistence + # and migrations under the user's home directory. To keep those specs + # hermetic we swap in a fresh HOME for each example using this around + # hook. This balances performance (single suite-level HOME) with test + # correctness for file-based scenarios. + config.around(:each) do |example| + original_home = ENV["HOME"] + original_userprofile = ENV["USERPROFILE"] + tmp_home = Dir.mktmpdir("chef_licensing_spec_example_home") + ENV["HOME"] = tmp_home + ENV["USERPROFILE"] = tmp_home if Gem.win_platform? + begin + example.run + ensure + ENV["HOME"] = original_home + ENV["USERPROFILE"] = original_userprofile + FileUtils.remove_entry_secure(tmp_home) if ::File.exist?(tmp_home) + end + end + + # Clear cached configuration in the library before each example to avoid + # state leaking between tests. Many specs mutate `ChefLicensing::Config` + # (for example set a license_server_url or change logging/output) and + # rely on a clean slate. Reset only known, writable attributes here as + # a best-effort approach; this keeps examples deterministic without + # tightly coupling to private internals. + config.before(:each) do + if defined?(ChefLicensing::Config) + begin + ChefLicensing::Config.license_server_url = nil + ChefLicensing::Config.license_server_url_check_in_file = false + ChefLicensing::Config.logger = nil + ChefLicensing::Config.output = nil + ChefLicensing::Config.make_licensing_optional = false + ChefLicensing::Config.is_local_license_service = nil + ChefLicensing::Config.chef_entitlement_id = nil + ChefLicensing::Config.chef_product_name = nil + ChefLicensing::Config.chef_executable_name = nil + rescue StandardError + # best-effort reset; if some writers are missing ignore and continue + end + end + end + # Enable flags like --only-failures and --next-failure config.example_status_persistence_file_path = ".rspec_status" # Disable RSpec exposing methods globally on `Module` and `main` config.disable_monkey_patching! + require "fileutils" config.expect_with :rspec do |c| c.syntax = :expect From 1528e14f19624407fc649f071437b1f958b84a1b Mon Sep 17 00:00:00 2001 From: John McCrae Date: Wed, 8 Oct 2025 19:24:43 +0600 Subject: [PATCH 2/2] Delete components/ruby/Gemfile.lock the gemfile.lock is only necessary for chef builds and adds unnecessary complexity when used with chef-licensing --- components/ruby/Gemfile.lock | 192 ----------------------------------- 1 file changed, 192 deletions(-) delete mode 100644 components/ruby/Gemfile.lock diff --git a/components/ruby/Gemfile.lock b/components/ruby/Gemfile.lock deleted file mode 100644 index dcaa9d9c0..000000000 --- a/components/ruby/Gemfile.lock +++ /dev/null @@ -1,192 +0,0 @@ -PATH - remote: . - specs: - chef-licensing (1.2.0) - activesupport (> 7.1.3.2, < 7.2) - chef-config (>= 15) - faraday (>= 1, < 2) - faraday-http-cache - mixlib-log (~> 3.0) - ostruct (~> 0.1.0) - tty-prompt (~> 0.23) - tty-spinner (~> 0.9.3) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.5.2) - base64 - benchmark (>= 0.3) - bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) - connection_pool (>= 2.2.5) - drb - i18n (>= 1.6, < 2) - logger (>= 1.4.2) - minitest (>= 5.1) - mutex_m - securerandom (>= 0.3) - tzinfo (~> 2.0) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) - ast (2.4.2) - base64 (0.3.0) - benchmark (0.4.1) - bigdecimal (3.3.0) - byebug (11.1.3) - chef-config (18.8.11) - addressable - chef-utils (= 18.8.11) - fuzzyurl - mixlib-config (>= 2.2.12, < 4.0) - mixlib-shellout (>= 2.0, < 4.0) - tomlrb (~> 1.2) - chef-utils (18.8.11) - concurrent-ruby - chefstyle (2.2.2) - rubocop (= 1.25.1) - coderay (1.1.3) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) - crack (1.0.0) - bigdecimal - rexml - diff-lcs (1.5.0) - drb (2.2.3) - faraday (1.10.4) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) - ruby2_keywords (>= 0.0.4) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.1) - faraday-excon (1.1.0) - faraday-http-cache (2.5.1) - faraday (>= 0.8) - faraday-httpclient (1.0.1) - faraday-multipart (1.1.1) - multipart-post (~> 2.0) - faraday-net_http (1.0.2) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - ffi (1.17.2-arm64-darwin) - ffi (1.17.2-x64-mingw-ucrt) - ffi (1.17.2-x86_64-darwin) - ffi (1.17.2-x86_64-linux-gnu) - ffi-win32-extensions (1.0.4) - ffi - fuzzyurl (0.9.0) - hashdiff (1.2.1) - i18n (1.14.7) - concurrent-ruby (~> 1.0) - logger (1.7.0) - method_source (1.0.0) - minitest (5.25.5) - mixlib-config (3.0.27) - tomlrb - mixlib-log (3.2.3) - ffi (>= 1.15.5) - mixlib-shellout (3.3.9) - chef-utils - mixlib-shellout (3.3.9-x64-mingw-ucrt) - chef-utils - ffi-win32-extensions (~> 1.0.3) - win32-process (~> 0.9) - wmi-lite (~> 1.0) - multipart-post (2.4.1) - mutex_m (0.3.0) - ostruct (0.1.0) - parallel (1.22.1) - parser (3.1.2.1) - ast (~> 2.4.1) - pastel (0.8.0) - tty-color (~> 0.5) - pry (0.14.1) - coderay (~> 1.1) - method_source (~> 1.0) - public_suffix (6.0.2) - rainbow (3.1.1) - rake (13.0.6) - regexp_parser (2.6.0) - rexml (3.2.8) - strscan (>= 3.0.9) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.0) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.0) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.0) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.0) - rubocop (1.25.1) - parallel (~> 1.10) - parser (>= 3.1.0.0) - rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml - rubocop-ast (>= 1.15.1, < 2.0) - ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.23.0) - parser (>= 3.1.1.0) - ruby-progressbar (1.11.0) - ruby2_keywords (0.0.5) - securerandom (0.4.1) - strscan (3.1.0) - tomlrb (1.3.0) - tty-color (0.6.0) - tty-cursor (0.7.1) - tty-prompt (0.23.1) - pastel (~> 0.8) - tty-reader (~> 0.8) - tty-reader (0.9.0) - tty-cursor (~> 0.7) - tty-screen (~> 0.8) - wisper (~> 2.0) - tty-screen (0.8.2) - tty-spinner (0.9.3) - tty-cursor (~> 0.7) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unicode-display_width (2.3.0) - webmock (3.25.1) - addressable (>= 2.8.0) - crack (>= 0.3.2) - hashdiff (>= 0.4.0, < 2.0.0) - win32-process (0.10.0) - ffi (>= 1.0.0) - wisper (2.0.1) - wmi-lite (1.0.7) - -PLATFORMS - arm64-darwin-22 - x64-mingw-ucrt - x86_64-darwin-19 - x86_64-darwin-21 - x86_64-linux - -DEPENDENCIES - byebug - chef-licensing! - chefstyle (~> 2.2, >= 2.2.2) - pry - rake (~> 13.0, >= 13.0.6) - rspec (~> 3.11) - webmock (~> 3.25, >= 3.25.1) - -BUNDLED WITH - 2.3.18