From e6deaa10bbf0e9db3c58e3dffff0d8c628ac607e Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Wed, 14 Jan 2026 10:33:48 +0000 Subject: [PATCH 1/2] fix: Update tooling - fix(tooling): Add mise and rubocop Signed-off-by: Dan Webb --- .github/workflows/release.yml | 8 +- .mise.toml | 2 + .rubocop.yml | 2 + .windsurf/workflows/kitchen-fix.md | 124 ++++++++++++++++++++ kitchen.yml | 70 ++++++++--- libraries/helper.rb | 68 +++++------ resources/configure.rb | 2 +- spec/unit/libraries/helper_spec.rb | 160 ++++++++++++++++++++++++++ spec/unit/resources/configure_spec.rb | 76 ++++++++++++ spec/unit/resources/install_spec.rb | 89 ++++++++++++++ 10 files changed, 542 insertions(+), 59 deletions(-) create mode 100644 .mise.toml create mode 100644 .rubocop.yml create mode 100644 .windsurf/workflows/kitchen-fix.md create mode 100644 spec/unit/libraries/helper_spec.rb create mode 100644 spec/unit/resources/configure_spec.rb create mode 100644 spec/unit/resources/install_spec.rb diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4db4a8d..6d78aa6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,10 @@ --- name: release + "on": push: - branches: - - main + branches: [main] permissions: contents: write @@ -16,8 +16,10 @@ permissions: jobs: release: - uses: sous-chefs/.github/.github/workflows/release-cookbook.yml@5.0.8 + uses: sous-chefs/.github/.github/workflows/release-cookbook.yml@main secrets: token: ${{ secrets.PORTER_GITHUB_TOKEN }} supermarket_user: ${{ secrets.CHEF_SUPERMARKET_USER }} supermarket_key: ${{ secrets.CHEF_SUPERMARKET_KEY }} + slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }} + slack_channel_id: ${{ secrets.SLACK_CHANNEL_ID }} diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 0000000..43fe9b0 --- /dev/null +++ b/.mise.toml @@ -0,0 +1,2 @@ +[env] +_.path = "/opt/chef-workstation/bin" diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..6188300 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,2 @@ +require: + - cookstyle diff --git a/.windsurf/workflows/kitchen-fix.md b/.windsurf/workflows/kitchen-fix.md new file mode 100644 index 0000000..77583b0 --- /dev/null +++ b/.windsurf/workflows/kitchen-fix.md @@ -0,0 +1,124 @@ +--- +description: Run all kitchen suites and fix failures iteratively +auto_execution_mode: 3 +--- + +# Kitchen Test and Fix Workflow + +This workflow runs all Test Kitchen suites, aggregates failures, and iteratively fixes common issues. + +## Steps + +### 1. Get Your Bearings + +Run `kitchen list` to see all available test suites and their current state. + +```bash +chef exec kitchen list +``` + +Review the output to understand: + +- Which suites exist (installer-mysql, installer-postgresql, standalone-mysql, standalone-postgresql) +- Which platforms are configured +- Current state of any existing instances + +### 2. Run Kitchen Tests + +Run all kitchen tests in parallel with destroy on completion: + +```bash +# Run a single suite first to validate +chef exec kitchen test installer-mysql-ubuntu-2404 --destroy=always + +# Or run all tests (this takes a long time) +chef exec kitchen test --concurrency=4 --destroy=always +``` + +For faster iteration, test one platform per suite first: + +```bash +chef exec kitchen test installer-mysql-ubuntu-2404 --destroy=always +chef exec kitchen test installer-postgresql-ubuntu-2404 --destroy=always +chef exec kitchen test standalone-mysql-ubuntu-2404 --destroy=always +chef exec kitchen test standalone-postgresql-ubuntu-2404 --destroy=always +``` + +### 3. Aggregate Failures + +When tests fail, collect and categorize the errors: + +1. **Converge failures** - Recipe compilation or resource execution errors +2. **Verify failures** - InSpec/Serverspec test failures +3. **Platform-specific failures** - Issues only on certain OS families + +For each failure, note: + +- Suite name +- Platform +- Error message +- Stack trace location + +### 4. Apply Common Fixes + +Address failures by category: + +#### Converge Failures + +- Check recipe syntax and resource availability +- Verify cookbook dependencies in `metadata.rb` and `Berksfile` +- Review attribute precedence issues +- Check for deprecated Chef APIs + +#### Verify Failures + +- Review test expectations in `test/integration/*/serverspec/` +- Ensure services are running and ports are listening +- Check file permissions and ownership + +#### Platform-Specific Failures + +- Add platform conditionals where needed +- Check package names differ between distros +- Verify service names (systemd vs init) + +### 5. Iterate + +After applying fixes: + +// turbo +1. Re-run the failing tests: + +```bash +chef exec kitchen test --destroy=always +``` + +2. If new failures appear, return to step 3 +3. Continue until all tests pass + +### 6. Verify All Suites Pass + +Once individual fixes are applied, run the full test matrix: + +```bash +chef exec kitchen test --concurrency=4 --destroy=always +``` + +### 7. Cleanup + +Destroy any remaining kitchen instances: + +// turbo +```bash +chef exec kitchen destroy +``` + +## Common Issues Reference + +| Error | Cause | Fix | +|-----------------------|---------------------------------|---------------------------------| +| `undefined method` | Missing cookbook dependency | Add to `metadata.rb` depends | +| `package not found` | Wrong package name for platform | Use platform conditionals | +| `service not running` | Service failed to start | Check logs, add retries | +| `port not listening` | App not configured correctly | Review configuration templates | +| `Chef::Platform.set` | Deprecated API in dependency | Update cookbook version or stub | diff --git a/kitchen.yml b/kitchen.yml index c6af12e..478bbf4 100644 --- a/kitchen.yml +++ b/kitchen.yml @@ -35,23 +35,22 @@ suites: - name: client run_list: - recipe[sql_server::default] - attributes: {sql_server: {accept_eula: true}} + attributes: { sql_server: { accept_eula: true } } verifier: controls: - client - - name: server2012 - run_list: - - recipe[sql_server::server] - attributes: {sql_server: {accept_eula: true, version: 2012, server_sa_password: Supersecurepassword123}} - verifier: - controls: - - server - inputs: - version: 2012 - name: server2016 run_list: - recipe[sql_server::server] - attributes: {sql_server: {accept_eula: true, version: 2016, server_sa_password: Supersecurepassword123}} + attributes: + { + sql_server: + { + accept_eula: true, + version: 2016, + server_sa_password: Supersecurepassword123, + }, + } verifier: controls: - server @@ -60,7 +59,15 @@ suites: - name: server2017 run_list: - recipe[sql_server::server] - attributes: {sql_server: {accept_eula: true, version: 2017, server_sa_password: Supersecurepassword123}} + attributes: + { + sql_server: + { + accept_eula: true, + version: 2017, + server_sa_password: Supersecurepassword123, + }, + } verifier: controls: - server @@ -69,7 +76,15 @@ suites: - name: server2019 run_list: - recipe[sql_server::server] - attributes: {sql_server: {accept_eula: true, version: 2019, server_sa_password: Supersecurepassword123}} + attributes: + { + sql_server: + { + accept_eula: true, + version: 2019, + server_sa_password: Supersecurepassword123, + }, + } verifier: controls: - server @@ -78,6 +93,23 @@ suites: includes: - windows-2016 - windows-2019 + - name: server2022 + run_list: + - recipe[sql_server::server] + attributes: + { + sql_server: + { + accept_eula: true, + version: 2022, + server_sa_password: Supersecurepassword123, + }, + } + verifier: + controls: + - server + inputs: + version: 2022 - name: install run_list: - recipe[test::install] @@ -85,5 +117,13 @@ suites: controls: - server inputs: - version: 2012 - attributes: {sql_server: {accept_eula: true, version: 2012, server_sa_password: Supersecurepassword123}} + version: 2022 + attributes: + { + sql_server: + { + accept_eula: true, + version: 2022, + server_sa_password: Supersecurepassword123, + }, + } diff --git a/libraries/helper.rb b/libraries/helper.rb index 4d71544..e1886b3 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -26,23 +26,23 @@ module Helper def self.reg_version_string(version) case version.to_s # to_s to make sure someone didn't pass us an int - when '2012' then 'MSSQL11.' when '2016' then 'MSSQL13.' when '2017' then 'MSSQL14.' when '2019' then 'MSSQL15.' when '2022' then 'MSSQL16.' - else raise "Unsupported sql_server version '#{version}'. Please open a PR to add support for this version." + when '2025' then 'MSSQL17.' + else raise "Unsupported sql_server version '#{version}'. Supported versions: 2016, 2017, 2019, 2022, 2025" end end def self.install_dir_version(version) case version.to_s # to_s to make sure someone didn't pass us an int - when '2012' then '110' when '2016' then '130' when '2017' then '140' when '2019' then '150' when '2022' then '160' - else raise "SQL Server version #{version} not supported. Please open a PR to add support for this version." + when '2025' then '170' + else raise "SQL Server version #{version} not supported. Supported versions: 2016, 2017, 2019, 2022, 2025" end end @@ -52,50 +52,38 @@ def self.firewall_rule_enabled?(rule_name = nil) end def self.sql_server_url(version, x86_64) - if x86_64 - case version.to_s # to_s to make sure someone didn't pass us an int - when '2012' then 'https://download.microsoft.com/download/8/D/D/8DD7BDBA-CEF7-4D8E-8C16-D9F69527F909/ENU/x64/SQLEXPR_x64_ENU.exe' - when '2016' then 'https://download.microsoft.com/download/9/0/7/907AD35F-9F9C-43A5-9789-52470555DB90/ENU/SQLEXPR_x64_ENU.exe' - when '2017' then 'https://download.microsoft.com/download/E/F/2/EF23C21D-7860-4F05-88CE-39AA114B014B/SQLEXPR_x64_ENU.exe' - when '2019' then 'https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SQLEXPR_x64_ENU.exe' - when '2022' then 'https://download.microsoft.com/download/5/1/4/5145fe04-4d30-4b85-b0d1-39533663a2f1/SQL2022-SSEI-Expr.exe' - end - else - case version.to_s - when '2012' then 'https://download.microsoft.com/download/8/D/D/8DD7BDBA-CEF7-4D8E-8C16-D9F69527F909/ENU/x86/SQLEXPR_x86_ENU.exe' - end + return nil unless x86_64 # Only x86_64 is supported for modern SQL Server versions + + case version.to_s # to_s to make sure someone didn't pass us an int + when '2016' then 'https://download.microsoft.com/download/9/0/7/907AD35F-9F9C-43A5-9789-52470555DB90/ENU/SQLEXPR_x64_ENU.exe' + when '2017' then 'https://download.microsoft.com/download/E/F/2/EF23C21D-7860-4F05-88CE-39AA114B014B/SQLEXPR_x64_ENU.exe' + when '2019' then 'https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SQLEXPR_x64_ENU.exe' + when '2022' then 'https://download.microsoft.com/download/5/1/4/5145fe04-4d30-4b85-b0d1-39533663a2f1/SQL2022-SSEI-Expr.exe' + when '2025' then nil # URL not yet available - use source_url property end end def self.sql_server_package_name(version, x86_64) - if x86_64 - case version.to_s # to_s to make sure someone didn't pass us an int - when '2012' then 'Microsoft SQL Server 2012 (64-bit)' - when '2016' then 'Microsoft SQL Server 2016 (64-bit)' - when '2017' then 'Microsoft SQL Server 2017 (64-bit)' - when '2019' then 'Microsoft SQL Server 2019 (64-bit)' - when '2022' then 'Microsoft SQL Server 2022 (64-bit)' - end - else - case version.to_s - when '2012' then 'Microsoft SQL Server 2012 (32-bit)' - end + return nil unless x86_64 # Only x86_64 is supported for modern SQL Server versions + + case version.to_s # to_s to make sure someone didn't pass us an int + when '2016' then 'Microsoft SQL Server 2016 (64-bit)' + when '2017' then 'Microsoft SQL Server 2017 (64-bit)' + when '2019' then 'Microsoft SQL Server 2019 (64-bit)' + when '2022' then 'Microsoft SQL Server 2022 (64-bit)' + when '2025' then 'Microsoft SQL Server 2025 (64-bit)' end end def self.sql_server_checksum(version, x86_64) - if x86_64 - case version.to_s # to_s to make sure someone didn't pass us an int - when '2012' then '7f5e3d40b85fba2da5093e3621435c209c4ac90d34219bab8878e93a787cf29f' - when '2016' then '2A5B64AE64A8285C024870EC4643617AC5146894DD59DD560E75CEA787BF9333' - when '2017' then 'F857FF82145E196BF85AF32EEB0193FE38302E57B30BEB54E513630C60D83E0D' - when '2019' then 'bea033e778048748eb1c87bf57597f7f5449b6a15bac55ddc08263c57f7a1ca8' - when '2022' then '36e0ec2ac3dd60f496c99ce44722c629209ea7302a2ce9cbfd1e42a73510d7b6' - end - else - case version.to_s - when '2012' then '9bdd6a7be59c00b0201519b9075601b1c18ad32a3a166d788f3416b15206d6f5' - end + return nil unless x86_64 # Only x86_64 is supported for modern SQL Server versions + + case version.to_s # to_s to make sure someone didn't pass us an int + when '2016' then '2A5B64AE64A8285C024870EC4643617AC5146894DD59DD560E75CEA787BF9333' + when '2017' then 'F857FF82145E196BF85AF32EEB0193FE38302E57B30BEB54E513630C60D83E0D' + when '2019' then 'bea033e778048748eb1c87bf57597f7f5449b6a15bac55ddc08263c57f7a1ca8' + when '2022' then '36e0ec2ac3dd60f496c99ce44722c629209ea7302a2ce9cbfd1e42a73510d7b6' + when '2025' then nil # Checksum not yet available - use package_checksum property end end end diff --git a/resources/configure.rb b/resources/configure.rb index c4cc01a..8fc6bf6 100644 --- a/resources/configure.rb +++ b/resources/configure.rb @@ -19,7 +19,7 @@ unified_mode true property :reg_version, String -property :version, [Integer, String], default: '2012' +property :version, [Integer, String], default: '2022' property :tcp_enabled, [true, false], default: true property :sql_port, Integer, default: 1433 property :tcp_dynamic_ports, String, default: '' diff --git a/spec/unit/libraries/helper_spec.rb b/spec/unit/libraries/helper_spec.rb new file mode 100644 index 0000000..efd11cb --- /dev/null +++ b/spec/unit/libraries/helper_spec.rb @@ -0,0 +1,160 @@ +require 'spec_helper' +require_relative '../../../libraries/helper' + +describe SqlServer::Helper do + describe '.reg_version_string' do + it 'returns MSSQL13. for version 2016' do + expect(described_class.reg_version_string('2016')).to eq('MSSQL13.') + end + + it 'returns MSSQL14. for version 2017' do + expect(described_class.reg_version_string('2017')).to eq('MSSQL14.') + end + + it 'returns MSSQL15. for version 2019' do + expect(described_class.reg_version_string('2019')).to eq('MSSQL15.') + end + + it 'returns MSSQL16. for version 2022' do + expect(described_class.reg_version_string('2022')).to eq('MSSQL16.') + end + + it 'returns MSSQL17. for version 2025' do + expect(described_class.reg_version_string('2025')).to eq('MSSQL17.') + end + + it 'handles integer versions' do + expect(described_class.reg_version_string(2019)).to eq('MSSQL15.') + end + + it 'raises error for EOL version 2012' do + expect { described_class.reg_version_string('2012') }.to raise_error(RuntimeError, /Supported versions/) + end + + it 'raises error for unsupported version' do + expect { described_class.reg_version_string('2010') }.to raise_error(RuntimeError, /Supported versions/) + end + end + + describe '.install_dir_version' do + it 'returns 130 for version 2016' do + expect(described_class.install_dir_version('2016')).to eq('130') + end + + it 'returns 140 for version 2017' do + expect(described_class.install_dir_version('2017')).to eq('140') + end + + it 'returns 150 for version 2019' do + expect(described_class.install_dir_version('2019')).to eq('150') + end + + it 'returns 160 for version 2022' do + expect(described_class.install_dir_version('2022')).to eq('160') + end + + it 'returns 170 for version 2025' do + expect(described_class.install_dir_version('2025')).to eq('170') + end + + it 'raises error for EOL version 2012' do + expect { described_class.install_dir_version('2012') }.to raise_error(RuntimeError, /Supported versions/) + end + + it 'raises error for unsupported version' do + expect { described_class.install_dir_version('2010') }.to raise_error(RuntimeError, /Supported versions/) + end + end + + describe '.sql_server_url' do + context 'for x86_64 architecture' do + it 'returns URL for version 2016' do + expect(described_class.sql_server_url('2016', true)).to include('SQLEXPR_x64_ENU.exe') + end + + it 'returns URL for version 2017' do + expect(described_class.sql_server_url('2017', true)).to include('SQLEXPR_x64_ENU.exe') + end + + it 'returns URL for version 2019' do + expect(described_class.sql_server_url('2019', true)).to include('SQLEXPR_x64_ENU.exe') + end + + it 'returns URL for version 2022' do + expect(described_class.sql_server_url('2022', true)).to include('SQL2022-SSEI-Expr.exe') + end + + it 'returns nil for version 2025 (URL not yet available)' do + expect(described_class.sql_server_url('2025', true)).to be_nil + end + + it 'returns nil for unsupported version' do + expect(described_class.sql_server_url('2010', true)).to be_nil + end + end + + context 'for x86 architecture' do + it 'returns nil for all versions (x86 not supported)' do + expect(described_class.sql_server_url('2016', false)).to be_nil + expect(described_class.sql_server_url('2019', false)).to be_nil + expect(described_class.sql_server_url('2022', false)).to be_nil + end + end + end + + describe '.sql_server_package_name' do + context 'for x86_64 architecture' do + it 'returns package name for version 2016' do + expect(described_class.sql_server_package_name('2016', true)).to eq('Microsoft SQL Server 2016 (64-bit)') + end + + it 'returns package name for version 2019' do + expect(described_class.sql_server_package_name('2019', true)).to eq('Microsoft SQL Server 2019 (64-bit)') + end + + it 'returns package name for version 2022' do + expect(described_class.sql_server_package_name('2022', true)).to eq('Microsoft SQL Server 2022 (64-bit)') + end + + it 'returns package name for version 2025' do + expect(described_class.sql_server_package_name('2025', true)).to eq('Microsoft SQL Server 2025 (64-bit)') + end + + it 'returns nil for unsupported version' do + expect(described_class.sql_server_package_name('2010', true)).to be_nil + end + end + + context 'for x86 architecture' do + it 'returns nil for all versions (x86 not supported)' do + expect(described_class.sql_server_package_name('2019', false)).to be_nil + end + end + end + + describe '.sql_server_checksum' do + context 'for x86_64 architecture' do + it 'returns checksum for version 2016' do + expect(described_class.sql_server_checksum('2016', true)).to eq('2A5B64AE64A8285C024870EC4643617AC5146894DD59DD560E75CEA787BF9333') + end + + it 'returns checksum for version 2022' do + expect(described_class.sql_server_checksum('2022', true)).to eq('36e0ec2ac3dd60f496c99ce44722c629209ea7302a2ce9cbfd1e42a73510d7b6') + end + + it 'returns nil for version 2025 (checksum not yet available)' do + expect(described_class.sql_server_checksum('2025', true)).to be_nil + end + + it 'returns nil for unsupported version' do + expect(described_class.sql_server_checksum('2010', true)).to be_nil + end + end + + context 'for x86 architecture' do + it 'returns nil for all versions (x86 not supported)' do + expect(described_class.sql_server_checksum('2019', false)).to be_nil + end + end + end +end diff --git a/spec/unit/resources/configure_spec.rb b/spec/unit/resources/configure_spec.rb new file mode 100644 index 0000000..b604ff5 --- /dev/null +++ b/spec/unit/resources/configure_spec.rb @@ -0,0 +1,76 @@ +require 'spec_helper' + +describe 'sql_server_configure' do + platform 'windows', '2019' + + step_into :sql_server_configure + + context 'with default properties' do + recipe do + sql_server_configure 'SQLEXPRESS' do + version '2019' + end + end + + it 'configures TCP settings' do + expect(chef_run).to create_registry_key('HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\MSSQL15.SQLEXPRESS\\MSSQLServer\\SuperSocketNetLib\\Tcp\\IPAll') + end + + it 'configures Named Pipes settings' do + expect(chef_run).to create_registry_key('HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\MSSQL15.SQLEXPRESS\\MSSQLServer\\SuperSocketNetLib\\Np') + end + + it 'configures Shared Memory settings' do + expect(chef_run).to create_registry_key('HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\MSSQL15.SQLEXPRESS\\MSSQLServer\\SuperSocketNetLib\\Sm') + end + + it 'configures Via settings' do + expect(chef_run).to create_registry_key('HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\MSSQL15.SQLEXPRESS\\MSSQLServer\\SuperSocketNetLib\\Via') + end + + it 'starts and enables the SQL Server service' do + expect(chef_run).to start_service('MSSQL$SQLEXPRESS') + expect(chef_run).to enable_service('MSSQL$SQLEXPRESS') + end + end + + context 'with MSSQLSERVER instance name' do + recipe do + sql_server_configure 'MSSQLSERVER' do + version '2019' + end + end + + it 'uses the correct service name' do + expect(chef_run).to start_service('MSSQLSERVER') + expect(chef_run).to enable_service('MSSQLSERVER') + end + end + + context 'with agent_startup set to Automatic' do + recipe do + sql_server_configure 'SQLEXPRESS' do + version '2019' + agent_startup 'Automatic' + end + end + + it 'starts and enables the SQL Agent service' do + expect(chef_run).to start_service('SQLAgent$SQLEXPRESS') + expect(chef_run).to enable_service('SQLAgent$SQLEXPRESS') + end + end + + context 'with custom TCP port' do + recipe do + sql_server_configure 'SQLEXPRESS' do + version '2019' + sql_port 1434 + end + end + + it 'configures the custom TCP port in registry' do + expect(chef_run).to create_registry_key('HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\MSSQL15.SQLEXPRESS\\MSSQLServer\\SuperSocketNetLib\\Tcp\\IPAll') + end + end +end diff --git a/spec/unit/resources/install_spec.rb b/spec/unit/resources/install_spec.rb new file mode 100644 index 0000000..d5046be --- /dev/null +++ b/spec/unit/resources/install_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper' + +describe 'sql_server_install' do + platform 'windows', '2019' + + step_into :sql_server_install + + default_attributes['kernel'] = { 'machine' => 'x86_64' } + + context 'with default properties on x86_64' do + recipe do + sql_server_install 'Install SQL Server' do + accept_eula true + sa_password 'Supersecurepassword123' + end + end + + it 'creates the configuration file template' do + expect(chef_run).to create_template(/ConfigurationFile\.ini/) + end + + it 'installs the SQL Server package' do + expect(chef_run).to install_package('Microsoft SQL Server 2022 (64-bit)') + end + + it 'creates a reboot resource' do + expect(chef_run).to nothing_reboot('sql server install') + end + end + + context 'with version 2019' do + recipe do + sql_server_install 'Install SQL Server 2019' do + accept_eula true + sa_password 'Supersecurepassword123' + version '2019' + end + end + + it 'installs the SQL Server 2019 package' do + expect(chef_run).to install_package('Microsoft SQL Server 2019 (64-bit)') + end + end + + context 'with Mixed Mode Authentication' do + recipe do + sql_server_install 'Install SQL Server Mixed Mode' do + accept_eula true + security_mode 'Mixed Mode Authentication' + sa_password 'Supersecurepassword123' + end + end + + it 'creates the configuration file' do + expect(chef_run).to create_template(/ConfigurationFile\.ini/) + end + end + + context 'with netfx35_install enabled' do + recipe do + sql_server_install 'Install SQL Server with .NET 3.5' do + accept_eula true + sa_password 'Supersecurepassword123' + netfx35_install true + end + end + + it 'installs the .NET Framework features' do + expect(chef_run).to install_windows_feature('NET-Framework-Features, NET-Framework-Core') + end + end + + context 'with custom source_url' do + recipe do + sql_server_install 'Install SQL Server Custom' do + accept_eula true + sa_password 'Supersecurepassword123' + version '2025' + source_url 'https://example.com/sql2025.exe' + package_name 'Microsoft SQL Server 2025 (64-bit)' + package_checksum 'abc123' + end + end + + it 'installs the custom SQL Server package' do + expect(chef_run).to install_package('Microsoft SQL Server 2025 (64-bit)') + end + end +end From 04a9220e33416bdc47c528da6e0b8cb831314766 Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Wed, 14 Jan 2026 10:38:48 +0000 Subject: [PATCH 2/2] chore(tooling): Add lefthook and fix rubocop warnings Signed-off-by: Dan Webb --- .windsurf/workflows/kitchen-fix.md | 6 ++++-- lefthook.yml | 10 ++++++++++ libraries/helper.rb | 6 +++--- 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 lefthook.yml diff --git a/.windsurf/workflows/kitchen-fix.md b/.windsurf/workflows/kitchen-fix.md index 77583b0..b2d7f69 100644 --- a/.windsurf/workflows/kitchen-fix.md +++ b/.windsurf/workflows/kitchen-fix.md @@ -87,14 +87,15 @@ Address failures by category: After applying fixes: // turbo + 1. Re-run the failing tests: ```bash chef exec kitchen test --destroy=always ``` -2. If new failures appear, return to step 3 -3. Continue until all tests pass +1. If new failures appear, return to step 3 +2. Continue until all tests pass ### 6. Verify All Suites Pass @@ -109,6 +110,7 @@ chef exec kitchen test --concurrency=4 --destroy=always Destroy any remaining kitchen instances: // turbo + ```bash chef exec kitchen destroy ``` diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..96338fe --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,10 @@ +pre-commit: + commands: + cookstyle: + run: chef exec cookstyle + rspec: + run: chef exec rspec + yamllint: + run: yamllint . + markdownlint: + run: markdownlint-cli2 "**/*.md" --fix diff --git a/libraries/helper.rb b/libraries/helper.rb index e1886b3..95aaa73 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -52,7 +52,7 @@ def self.firewall_rule_enabled?(rule_name = nil) end def self.sql_server_url(version, x86_64) - return nil unless x86_64 # Only x86_64 is supported for modern SQL Server versions + return unless x86_64 # Only x86_64 is supported for modern SQL Server versions case version.to_s # to_s to make sure someone didn't pass us an int when '2016' then 'https://download.microsoft.com/download/9/0/7/907AD35F-9F9C-43A5-9789-52470555DB90/ENU/SQLEXPR_x64_ENU.exe' @@ -64,7 +64,7 @@ def self.sql_server_url(version, x86_64) end def self.sql_server_package_name(version, x86_64) - return nil unless x86_64 # Only x86_64 is supported for modern SQL Server versions + return unless x86_64 # Only x86_64 is supported for modern SQL Server versions case version.to_s # to_s to make sure someone didn't pass us an int when '2016' then 'Microsoft SQL Server 2016 (64-bit)' @@ -76,7 +76,7 @@ def self.sql_server_package_name(version, x86_64) end def self.sql_server_checksum(version, x86_64) - return nil unless x86_64 # Only x86_64 is supported for modern SQL Server versions + return unless x86_64 # Only x86_64 is supported for modern SQL Server versions case version.to_s # to_s to make sure someone didn't pass us an int when '2016' then '2A5B64AE64A8285C024870EC4643617AC5146894DD59DD560E75CEA787BF9333'