Add acceptance tests for git protocols using clone
authorJohn Duarte <john.duarte@puppetlabs.com>
Mon, 5 May 2014 21:02:51 +0000 (14:02 -0700)
committerJohn Duarte <john.duarte@puppetlabs.com>
Thu, 8 May 2014 03:11:46 +0000 (20:11 -0700)
The git_clone_protocols_spec.rb will be used to enumerate over the
available protocols for git to use to clone to disk. Support
key files are also included for https/ssl use.

Protocols tested

    * file protocol (raw filepath)
    * file protocol (file://)
    * git protocol (git://)
    * http protocol (http://)
    * https protocol (https://)
    * ssh protocol (ssh://user@host)

TODO: Currently, the ssl cert is not added to the CA on the host.
This causes the git clone to fail because the cert is not trusted
and the client does not proceed with a non-trusted ssl connection.

spec/acceptance/files/create_git_repo.sh
spec/acceptance/files/server.crt [new file with mode: 0644]
spec/acceptance/files/server.key [new file with mode: 0644]
spec/acceptance/git_clone_protocols_spec.rb [new file with mode: 0644]

index 03c4f44..40f341a 100755 (executable)
@@ -34,3 +34,6 @@ cd ..
 git --git-dir=testrepo/.git config core.bare true
 cp -r testrepo/.git testrepo.git
 rm -rf testrepo
+cd testrepo.git
+touch git-daemon-export-ok
+git update-server-info
diff --git a/spec/acceptance/files/server.crt b/spec/acceptance/files/server.crt
new file mode 100644 (file)
index 0000000..ef1de5a
--- /dev/null
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQCS3fQotV10LzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTE0MDQyMzIyMzEyM1oXDTE1MDQyMzIyMzEyM1owRTELMAkG
+A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyRTv
+uX6328aQ5Auc8PI+xNaCiE0UZNYcs+xq3AEkR/Tnz0HGXdx3+PnFG7MIRSS65hXA
+VGenZk3wP4vNIe9gu+G9jtOFTJOgoOBUnJ/Hcs79Zgcmz3cAWQpqww+CZpyngUDS
+msZ5HoEbNS+qaIron3IrYCgPsy1BHFs5ze7JrtcCAwEAATANBgkqhkiG9w0BAQUF
+AAOBgQA2uLvdc1cf+nt7d8Lmu0SdaoIsCzh6DjVscCpFJKXdDjGT2Ys40iKbLRnY
+Tt98wa6uRzEhSKfx+zVi8n3PSkQHlER7jzKFXMVx8NEt2/O/APKXVizmLFjk5WcT
+FvGmmbkqX+Nj9TUTuSRZEmF776r5k8U5ABu/VarxvAzyoXAhqA==
+-----END CERTIFICATE-----
diff --git a/spec/acceptance/files/server.key b/spec/acceptance/files/server.key
new file mode 100644 (file)
index 0000000..b594f13
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDJFO+5frfbxpDkC5zw8j7E1oKITRRk1hyz7GrcASRH9OfPQcZd
+3Hf4+cUbswhFJLrmFcBUZ6dmTfA/i80h72C74b2O04VMk6Cg4FScn8dyzv1mBybP
+dwBZCmrDD4JmnKeBQNKaxnkegRs1L6poiuifcitgKA+zLUEcWznN7smu1wIDAQAB
+AoGAQPnD8OOyk5DZVuctwmn0wHQ0X8jQczkAs18MtKSlzZ6knUM6zy+jkM9c0vOK
+E5Wn0xtqN5v66sL6g/4vvex1DA5Q6YsXvZ48VpVliZXXK/1pdTv0qwMyHdlBhmgJ
+MhnZbyNy61QHdOTsWDR1YrELpDyFMJ9cZZD0NOnsuhd2DbECQQDq7W/zlJBZPWNR
+ab2dP+HLpm/PiEBT13SuEEskh3GEEfZlwz/cGu0Z8DHA4E3Z60KFjwgnc92GNFMg
+m0t3hHtpAkEA2x5PsDxBk9sWwdIvu57vjQLdotvAfyb+W9puIaZS1JRSVLTsUVEj
+Y0KxgsPHtcjrVoN//zGymn4ePxWOzlrQPwJBAN5thEuZY7o6dyiD9zVFYKGSqdZS
+aKV5H04Wuy6Q1pd28lWTMYlSLR8b3d+B//PN3SPbMps4BoukSvhaUG+OjdECQFzF
+KZIBAPa7pJftCH6UHPIDy5ifF5H+DWUQRt6CT8FnBrCMZR1MkAH/g65Me6pwZYsc
+Y73E6cxVJzMoSmz9r/sCQQCOhPflFCxZ23ocsuRBo9O/mMUDaLoHZXWuJ2DqAUN2
+mS6UUR/lpyc7Cmy0VOyhS8783D7MUfji5ddfVxb5tWgm
+-----END RSA PRIVATE KEY-----
diff --git a/spec/acceptance/git_clone_protocols_spec.rb b/spec/acceptance/git_clone_protocols_spec.rb
new file mode 100644 (file)
index 0000000..f59644e
--- /dev/null
@@ -0,0 +1,230 @@
+require 'spec_helper_acceptance'
+
+hosts.each do |host|
+
+  describe 'clones a repo with git' do
+    tmpdir =  host.tmpdir('vcsrepo')
+
+    before(:all) do
+      # {{{ setup
+      on(host,apply_manifest("user{'testuser': ensure => present, managehome => true }"))
+      on(host,apply_manifest("user{'vagrant': ensure => present, }"))
+      # install git
+      install_package(host, 'git')
+      install_package(host, 'git-daemon')
+      # create ssh keys
+      host.execute('mkdir -p /home/testuser/.ssh')
+      host.execute('ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ""')
+
+      # copy public key to authorized_keys
+      host.execute('cat /root/.ssh/id_rsa.pub >> /home/testuser/.ssh/authorized_keys')
+      host.execute('echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /home/testuser/.ssh/config')
+      host.execute('echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config')
+      host.execute('chown -R testuser:testuser /home/testuser/.ssh')
+      host.execute('chown -R root:root /root/.ssh')
+
+      # create git repo
+      my_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+      scp_to(host, "#{my_root}/acceptance/files/create_git_repo.sh", tmpdir)
+      host.execute("cd #{tmpdir} && ./create_git_repo.sh")
+
+      # copy ssl keys
+      scp_to(host, "#{my_root}/acceptance/files/server.crt", tmpdir)
+      scp_to(host, "#{my_root}/acceptance/files/server.key", tmpdir)
+      # }}}
+    end
+
+    after(:all) do
+      # {{{ teardown
+      on(host,apply_manifest("user{'testuser': ensure => absent, managehome => true }"))
+      on(host,apply_manifest("file{'/root/.ssh/id_rsa': ensure => absent, force => true }"))
+      on(host,apply_manifest("file{'/root/.ssh/id_rsa.pub': ensure => absent, force => true }"))
+      # }}}
+    end
+
+
+    #---------------  TESTS ----------------------#
+
+    context 'using local protocol (file URL)' do
+      before(:all) do
+        on(host,apply_manifest("file {'#{tmpdir}/testrepo': ensure => directory, purge => true, recurse => true, recurselimit => 1, force => true; }"))
+      end
+
+      it 'should have HEAD pointing to master' do
+        pp = <<-EOS
+        vcsrepo { "#{tmpdir}/testrepo":
+          ensure => present,
+          provider => git,
+          source => "file://#{tmpdir}/testrepo.git",
+        }
+        EOS
+
+        # Run it twice and test for idempotency
+        on(host,apply_manifest(pp, :catch_failures => true))
+        on(host,apply_manifest(pp, :catch_changes => true))
+      end
+
+      describe file("#{tmpdir}/testrepo/.git/HEAD") do
+        it { should contain 'ref: refs/heads/master' }
+      end
+
+    end
+
+    context 'using local protocol (file path)' do
+      before(:all) do
+        on(host,apply_manifest("file {'#{tmpdir}/testrepo': ensure => directory, purge => true, recurse => true, recurselimit => 1, force => true; }"))
+      end
+
+      it 'should have HEAD pointing to master' do
+        pp = <<-EOS
+        vcsrepo { "#{tmpdir}/testrepo":
+          ensure => present,
+          provider => git,
+          source => "#{tmpdir}/testrepo.git",
+        }
+        EOS
+
+        # Run it twice and test for idempotency
+        on(host,apply_manifest(pp, :catch_failures => true))
+        on(host,apply_manifest(pp, :catch_changes => true))
+      end
+
+      describe file("#{tmpdir}/testrepo/.git/HEAD") do
+        it { should contain 'ref: refs/heads/master' }
+      end
+
+    end
+
+    context 'using git protocol' do
+      before(:all) do
+        on(host,apply_manifest("file {'#{tmpdir}/testrepo': ensure => directory, purge => true, recurse => true, recurselimit => 1, force => true; }"))
+        host.execute("nohup git daemon  --detach --base-path=/#{tmpdir}")
+      end
+
+      it 'should have HEAD pointing to master' do
+        pp = <<-EOS
+        vcsrepo { "#{tmpdir}/testrepo":
+          ensure => present,
+          provider => git,
+          source => "git://#{host}/testrepo.git",
+        }
+        EOS
+
+        # Run it twice and test for idempotency
+        apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
+      end
+      describe file("#{tmpdir}/testrepo/.git/HEAD") do
+        it { should contain 'ref: refs/heads/master' }
+      end
+
+      after(:all) do
+        host.execute('pkill -9 git')
+      end
+    end
+
+    context 'using http protocol' do
+      before(:all) do
+        on(host,apply_manifest("file {'#{tmpdir}/testrepo': ensure => directory, purge => true, recurse => true, recurselimit => 1, force => true; }"))
+        daemon =<<-EOF
+        require 'webrick'
+        server = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => "#{tmpdir}")
+        WEBrick::Daemon.start
+        server.start
+        EOF
+        create_remote_file(host, '/tmp/daemon.rb', daemon)
+        on(host, "ruby /tmp/daemon.rb")
+      end
+
+      it 'should have HEAD pointing to master' do
+        pp = <<-EOS
+        vcsrepo { "#{tmpdir}/testrepo":
+          ensure => present,
+          provider => git,
+          source => "http://#{host}:8000/testrepo.git",
+        }
+        EOS
+
+        # Run it twice and test for idempotency
+        apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
+      end
+      describe file("#{tmpdir}/testrepo/.git/HEAD") do
+        it { should contain 'ref: refs/heads/master' }
+      end
+
+      after(:all) do
+        host.execute('pkill -9 ruby')
+      end
+    end
+
+    context 'using https protocol' do
+      before(:all) do
+        on(host,apply_manifest("file {'#{tmpdir}/testrepo': ensure => directory, purge => true, recurse => true, recurselimit => 1, force => true; }"))
+        daemon =<<-EOF
+        require 'webrick'
+        require 'webrick/https'
+        server = WEBrick::HTTPServer.new(
+        :Port               => 8443,
+        :DocumentRoot       => "#{tmpdir}",
+        :SSLEnable          => true,
+        :SSLVerifyClient    => OpenSSL::SSL::VERIFY_NONE,
+        :SSLCertificate     => OpenSSL::X509::Certificate.new(  File.open("#{tmpdir}/server.crt").read),
+        :SSLPrivateKey      => OpenSSL::PKey::RSA.new(          File.open("#{tmpdir}/server.key").read),
+        :SSLCertName        => [ [ "CN",WEBrick::Utils::getservername ] ])
+        WEBrick::Daemon.start
+        server.start
+        EOF
+        create_remote_file(host, '/tmp/daemon.rb', daemon)
+        on(host, "ruby /tmp/daemon.rb")
+      end
+
+      it 'should have HEAD pointing to master' do
+        # howto whitelist ssl cert
+        pp = <<-EOS
+        vcsrepo { "#{tmpdir}/testrepo":
+          ensure => present,
+          provider => git,
+          source => "https://#{host}:8443/testrepo.git",
+        }
+        EOS
+
+        # Run it twice and test for idempotency
+        apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
+      end
+
+      describe file("#{tmpdir}/testrepo/.git/HEAD") do
+        it { should contain 'ref: refs/heads/master' }
+      end
+
+      after(:all) do
+        host.execute('pkill -9 ruby')
+      end
+    end
+
+    context 'using ssh protocol' do
+      before(:all) do
+        on(host,apply_manifest("file {'#{tmpdir}/testrepo': ensure => directory, purge => true, recurse => true, recurselimit => 1, force => true; }"))
+      end
+      it 'should have HEAD pointing to master' do
+        pp = <<-EOS
+        vcsrepo { "#{tmpdir}/testrepo":
+          ensure => present,
+          provider => git,
+          source => "ssh://root@#{host}#{tmpdir}/testrepo.git",
+        }
+        EOS
+
+        # Run it twice and test for idempotency
+        apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
+      end
+
+      describe file("#{tmpdir}/testrepo/.git/HEAD") do
+        it { should contain 'ref: refs/heads/master' }
+      end
+    end
+
+  end
+end