(maint) reduce run time for acceptance testing
authortphoney <tp@puppet.com>
Thu, 14 Feb 2019 10:23:04 +0000 (10:23 +0000)
committertphoney <tp@puppet.com>
Mon, 4 Mar 2019 14:13:48 +0000 (14:13 +0000)
Moving acceptance tests to unit tests, this reduces run time for testing.
This gives a 50% reduction in acceptance test times.

spec/acceptance/apt_key_provider_spec.rb
spec/spec_helper_acceptance.rb
spec/unit/puppet/provider/apt_key_spec.rb [new file with mode: 0644]

index fdb2ec63d0f35bc02b1234ff461b96d0aa99ded1..f3dc4d38889755b99c1eddf0dcdb5c8dbb019872 100644 (file)
@@ -19,16 +19,6 @@ CENTOS_KEY_CHECK_COMMAND            = "#{KEY_CHECK_COMMAND} #{CENTOS_GPG_KEY_FIN
 PUPPETLABS_EXP_CHECK_COMMAND        = "#{KEY_CHECK_COMMAND} '#{PUPPETLABS_EXP_KEY_DATES}'".freeze
 DEBIAN_PUPPETLABS_EXP_CHECK_COMMAND = 'apt-key list | grep -F -A 1 \'pub   rsa4096 2010-07-10 [SC] [expired: 2017-01-05]\' | grep \'47B3 20EB 4C7C 375A A9DA  E1A0 1054 B7A2 4BD6 EC30\''.freeze
 
-def populate_default_options_pp(value)
-  default_options_pp = <<-MANIFEST
-          apt_key { 'puppetlabs':
-            id     => '#{value}',
-            ensure => 'present',
-          }
-  MANIFEST
-  default_options_pp
-end
-
 def install_key(key)
   retry_on_error_matching do
     shell("apt-key adv --no-tty --keyserver pgp.mit.edu --recv-keys #{key}")
@@ -44,26 +34,6 @@ def apply_manifest_twice(manifest_pp)
   end
 end
 
-invalid_key_length_pp = <<-MANIFEST
-        apt_key { 'puppetlabs':
-          id => '8280EF8D349F',
-        }
-  MANIFEST
-
-ensure_absent_pp = <<-MANIFEST
-        apt_key { 'centos':
-          id     => '#{CENTOS_GPG_KEY_LONG_ID}',
-          ensure => 'absent',
-        }
-  MANIFEST
-
-ensure_absent_long_key_pp = <<-MANIFEST
-        apt_key { 'puppetlabs':
-          id     => '#{PUPPETLABS_GPG_KEY_LONG_ID}',
-          ensure => 'absent',
-        }
-  MANIFEST
-
 refresh_pp = <<-MANIFEST
         apt_key { '#{PUPPETLABS_EXP_KEY_LONG_ID}':
           id      => '#{PUPPETLABS_EXP_KEY_LONG_ID}',
@@ -462,19 +432,11 @@ bogus_key_pp = <<-MANIFEST
         }
   MANIFEST
 
-hkps_pool_pp = <<-MANIFEST
-        apt_key { 'puppetlabs':
-          id     => '#{PUPPETLABS_GPG_KEY_LONG_ID}',
-          ensure => 'present',
-          server => 'pgp.mit.edu',
-        }
-  MANIFEST
-
 hkp_pool_pp = <<-MANIFEST
         apt_key { 'puppetlabs':
           id     => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}',
           ensure => 'present',
-          server => 'hkp://pgp.mit.edu:80',
+          server => 'hkp://keyserver.ubuntu.com:80',
         }
   MANIFEST
 
@@ -681,68 +643,26 @@ describe 'apt_key' do
           acceptable_exit_codes: [0, 1, 2])
   end
 
-  describe 'default options' do
-    key_versions = {
-      '32bit key id'                        => PUPPETLABS_GPG_KEY_SHORT_ID.to_s,
-      '64bit key id'                        => PUPPETLABS_GPG_KEY_LONG_ID.to_s,
-      '160bit key fingerprint'              => PUPPETLABS_GPG_KEY_FINGERPRINT.to_s,
-      '32bit lowercase key id'              => PUPPETLABS_GPG_KEY_SHORT_ID.downcase.to_s,
-      '64bit lowercase key id'              => PUPPETLABS_GPG_KEY_LONG_ID.downcase.to_s,
-      '160bit lowercase key fingerprint'    => PUPPETLABS_GPG_KEY_FINGERPRINT.downcase.to_s,
-      '0x formatted 32bit key id'           => "0x#{PUPPETLABS_GPG_KEY_SHORT_ID}",
-      '0x formatted 64bit key id'           => "0x#{PUPPETLABS_GPG_KEY_LONG_ID}",
-      '0x formatted 160bit key fingerprint' => "0x#{PUPPETLABS_GPG_KEY_FINGERPRINT}",
-      '0x formatted 32bit lowercase key id' => "0x#{PUPPETLABS_GPG_KEY_SHORT_ID.downcase}",
-      '0x formatted 64bit lowercase key id' => "0x#{PUPPETLABS_GPG_KEY_LONG_ID.downcase}",
-      '0x formatted 160bit lowercase key fingerprint' => "0x#{PUPPETLABS_GPG_KEY_FINGERPRINT.downcase}",
-    }
-
-    key_versions.each do |key, value| # rubocop:disable Lint/UnusedBlockArgument
-      context 'when key.to_s' do
-        it 'works' do
-          apply_manifest_twice(populate_default_options_pp(value))
-          shell(PUPPETLABS_KEY_CHECK_COMMAND)
-        end
-      end
-    end
-
-    context 'with invalid length key id' do
-      it 'fails' do
-        apply_manifest(invalid_key_length_pp, expect_failures: true) do |r|
-          expect(r.stderr).to match(%r{Valid values match})
-        end
-      end
-    end
-  end
-
   describe 'ensure =>' do
-    context 'when absent' do
-      it 'is removed' do
-        # Install the key first (retry because key pool may timeout)
-        install_key(CENTOS_GPG_KEY_FINGERPRINT)
-        shell(CENTOS_KEY_CHECK_COMMAND)
-
-        # Time to remove it using Puppet
-        apply_manifest_twice(ensure_absent_pp)
+    ensure_present_pp = <<-MANIFEST
+            apt_key { 'centos':
+              id     => '#{CENTOS_GPG_KEY_LONG_ID}',
+              ensure => 'present',
+            }
+      MANIFEST
 
-        shell(CENTOS_KEY_CHECK_COMMAND, acceptable_exit_codes: [1])
+    ensure_absent_pp = <<-MANIFEST
+            apt_key { 'centos':
+              id     => '#{CENTOS_GPG_KEY_LONG_ID}',
+              ensure => 'absent',
+            }
+      MANIFEST
 
-        # Re-Install the key (retry because key pool may timeout)
-        install_key(CENTOS_GPG_KEY_FINGERPRINT)
-      end
+    it 'add an apt_key resource' do
+      apply_manifest_twice(ensure_present_pp)
     end
-
-    context 'when absent, added with long key' do
-      it 'is removed' do
-        # Install the key first (retry because key pool may timeout)
-        install_key(PUPPETLABS_GPG_KEY_LONG_ID)
-        shell(PUPPETLABS_KEY_CHECK_COMMAND)
-
-        # Time to remove it using Puppet
-        apply_manifest_twice(ensure_absent_long_key_pp)
-
-        shell(PUPPETLABS_KEY_CHECK_COMMAND, acceptable_exit_codes: [1])
-      end
+    it 'remove the apt_key resource' do
+      apply_manifest_twice(ensure_absent_pp)
     end
   end
 
@@ -776,18 +696,6 @@ describe 'apt_key' do
   end
 
   describe 'server =>' do
-    context 'with pgp.mit.edu' do
-      it 'works' do
-        # Apply the manifest (Retry if timeout error is received from key pool)
-        retry_on_error_matching do
-          apply_manifest(hkps_pool_pp, catch_failures: true)
-        end
-
-        apply_manifest(hkps_pool_pp, catch_changes: true)
-        shell(PUPPETLABS_KEY_CHECK_COMMAND)
-      end
-    end
-
     context 'with hkp://pgp.mit.edu:80' do
       it 'works' do
         retry_on_error_matching do
index 91d1d02558d07fdcfdac7e06f5c5f95d62327389..29b178a51e3a8a125f65e273dc66e9e086c29658 100644 (file)
@@ -14,8 +14,8 @@ install_module_on(hosts)
 install_module_dependencies_on(hosts)
 
 UNSUPPORTED_PLATFORMS = ['RedHat', 'Suse', 'windows', 'AIX', 'Solaris'].freeze
-MAX_RETRY_COUNT       = 12
-RETRY_WAIT            = 10
+MAX_RETRY_COUNT       = 5
+RETRY_WAIT            = 3
 ERROR_MATCHER         = %r{(no valid OpenPGP data found|keyserver timed out|keyserver receive failed)}
 
 # This method allows a block to be passed in and if an exception is raised
@@ -36,7 +36,7 @@ def retry_on_error_matching(max_retry_count = MAX_RETRY_COUNT, retry_wait_interv
     try += 1
     yield
   rescue StandardError => e
-    raise unless try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher)
+    raise(_('Attempted this %{value0} times. Raising %{value1}') % { value0: max_retry_count, value1: e }) unless try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher)
     sleep retry_wait_interval_secs
     retry
   end
diff --git a/spec/unit/puppet/provider/apt_key_spec.rb b/spec/unit/puppet/provider/apt_key_spec.rb
new file mode 100644 (file)
index 0000000..a514793
--- /dev/null
@@ -0,0 +1,200 @@
+require 'spec_helper'
+
+describe Puppet::Type.type(:apt_key).provider(:apt_key) do
+  describe 'instances' do
+    it 'has an instance method' do
+      expect(described_class).to respond_to :instances
+    end
+  end
+
+  describe 'prefetch' do
+    it 'has a prefetch method' do
+      expect(described_class).to respond_to :prefetch
+    end
+  end
+
+  context 'self.instances no key' do
+    before :each do
+      allow(described_class).to receive(:apt_key).with(
+        ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'],
+      ).and_return('uid:-::::1284991450::07BEBE04F4AE4A8E885A761325717D8509D9C1DC::Ubuntu Extras Archive Automatic Signing Key <ftpmaster@ubuntu.com>::::::::::0:')
+    end
+    it 'returns no resources' do
+      expect(described_class.instances.size).to eq(0)
+    end
+  end
+
+  context 'self.instances multiple keys' do
+    before :each do
+      command_output = <<-OUTPUT
+Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --homedir /tmp/tmp.DU0GdRxjmE --no-auto-check-trustdb --trust-model always --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --keyring /etc/apt/trusted.gpg.d/puppetlabs-pc1-keyring.gpg --no-tty --list-keys --with-colons --fingerprint --fixed-list-mode
+tru:t:1:1549900774:0:3:1:5
+pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC:
+fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:
+uid:-::::1095016255::B84AE656F4F5A826C273A458512EF8E282754CE1::Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>:
+sub:-:2048:16:251BEFF479164387:1095016263::::::e:
+pub:-:1024:17:46181433FBB75451:1104433784:::-:::scSC:
+fpr:::::::::C5986B4F1257FFA86632CBA746181433FBB75451:
+OUTPUT
+      allow(described_class).to receive(:apt_key).with(
+        ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'],
+      ).and_return(command_output)
+    end
+    it 'returns 2 resources' do
+      expect(described_class.instances.size).to eq(2)
+      expect(described_class.instances[0].name).to eq('630239CC130E1A7FD81A27B140976EAF437D05B5')
+      expect(described_class.instances[0].id).to eq('40976EAF437D05B5')
+      expect(described_class.instances[1].name).to eq('C5986B4F1257FFA86632CBA746181433FBB75451')
+      expect(described_class.instances[1].id).to eq('46181433FBB75451')
+    end
+  end
+
+  context 'create apt_key resource' do
+    it 'apt_key with content set and source nil' do
+      expect(described_class).to receive(:apt_key).with(['adv', '--no-tty',
+                                                         '--keyserver',
+                                                         :"keyserver.ubuntu.com",
+                                                         '--recv-keys',
+                                                         'C105B9DE'])
+      resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
+                                           id: 'C105B9DE',
+                                           ensure: 'present')
+
+      provider = described_class.new(resource)
+      expect(provider).not_to be_exist
+      provider.create
+      expect(provider).to be_exist
+    end
+
+    it 'apt_key content and source nil, options set' do
+      expect(described_class).to receive(:apt_key).with(['adv', '--no-tty',
+                                                         '--keyserver',
+                                                         :"keyserver.ubuntu.com",
+                                                         '--keyserver-options',
+                                                         'jimno',
+                                                         '--recv-keys',
+                                                         'C105B9DE'])
+      resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
+                                           id: 'C105B9DE',
+                                           options: 'jimno',
+                                           ensure: 'present')
+
+      provider = described_class.new(resource)
+      expect(provider).not_to be_exist
+      provider.create
+      expect(provider).to be_exist
+    end
+
+    it 'apt_key with content set' do
+      expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
+      resource = Puppet::Type::Apt_key.new(name: 'gsd',
+                                           id: 'C105B9DE',
+                                           content: 'asad',
+                                           ensure: 'present')
+
+      provider = described_class.new(resource)
+      expect(provider).not_to be_exist
+      expect(provider).to receive(:tempfile).and_return(Tempfile.new('foo'))
+      provider.create
+      expect(provider).to be_exist
+    end
+
+    it 'apt_key with source set' do
+      expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
+      resource = Puppet::Type::Apt_key.new(name: 'gsd',
+                                           id: 'C105B9DE',
+                                           source: 'ftp://bla/herpderp.gpg',
+                                           ensure: 'present')
+
+      provider = described_class.new(resource)
+      expect(provider).not_to be_exist
+      expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo'))
+      provider.create
+      expect(provider).to be_exist
+    end
+
+    describe 'different valid id keys' do
+      hash_of_keys = {
+        '32bit key id' => 'EF8D349F',
+        '64bit key id' => '7F438280EF8D349F',
+        '160bit key fingerprint' => '6F6B15509CF8E59E6E469F327F438280EF8D349F',
+        '32bit key id lowercase' =>   'EF8D349F'.downcase,
+        '64bit key id lowercase' =>   '7F438280EF8D349F'.downcase,
+        '160bit key fingerprint lowercase' => '6F6B15509CF8E59E6E469F327F438280EF8D349F'.downcase,
+        '32bit key id 0x formatted' =>   '0xEF8D349F',
+        '64bit key id 0x formatted' =>   '0x7F438280EF8D349F',
+        '160bit key fingerprint 0x formatted' => '0x6F6B15509CF8E59E6E469F327F438280EF8D349F',
+      }
+      hash_of_keys.each do |key_type, value|
+        it "#{key_type} #{value} is valid" do
+          expect(described_class).to receive(:apt_key).with(array_including('adv', '--no-tty',
+                                                                            '--keyserver',
+                                                                            :"keyserver.ubuntu.com",
+                                                                            '--recv-keys'))
+          resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
+                                               id: value,
+                                               ensure: 'present')
+
+          provider = described_class.new(resource)
+          expect(provider).not_to be_exist
+          provider.create
+          expect(provider).to be_exist
+        end
+      end
+    end
+
+    it 'apt_key with invalid key length' do
+      expect {
+        Puppet::Type::Apt_key.new(name: 'source and content nil',
+                                  id: '1',
+                                  ensure: 'present')
+      }.to raise_error(Puppet::ResourceError, %r{Parameter id failed on Apt_key})
+    end
+  end
+
+  context 'key_line_hash function' do
+    it 'matches rsa' do
+      expect(described_class.key_line_hash('pub:-:1024:1:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
+        key_expiry: nil,
+        key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
+        key_long: '40976EAF437D05B5',
+        key_short: '437D05B5',
+        key_size: '1024',
+        key_type: :rsa,
+      )
+    end
+
+    it 'matches dsa' do
+      expect(described_class.key_line_hash('pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
+        key_expiry: nil,
+        key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
+        key_long: '40976EAF437D05B5',
+        key_short: '437D05B5',
+        key_size: '1024',
+        key_type: :dsa,
+      )
+    end
+
+    it 'matches ecc' do
+      expect(described_class.key_line_hash('pub:-:1024:18:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
+        key_expiry: nil,
+        key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
+        key_long: '40976EAF437D05B5',
+        key_short: '437D05B5',
+        key_size: '1024',
+        key_type: :ecc,
+      )
+    end
+
+    it 'matches ecdsa' do
+      expect(described_class.key_line_hash('pub:-:1024:19:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
+        key_expiry: nil,
+        key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
+        key_long: '40976EAF437D05B5',
+        key_short: '437D05B5',
+        key_size: '1024',
+        key_type: :ecdsa,
+      )
+    end
+  end
+end