mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
878d0d5b87
While tests are supposed to be run in docker, people might still want to use them on their own boxes.
661 lines
18 KiB
YAML
661 lines
18 KiB
YAML
# test code for the git module
|
|
# (c) 2014, James Tanner <tanner.jc@gmail.com>
|
|
|
|
# This file is part of Ansible
|
|
#
|
|
# Ansible is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Ansible is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
- name: set role facts
|
|
set_fact:
|
|
checkout_dir: '{{ output_dir }}/git'
|
|
repo_dir: '{{ output_dir }}/local_repos'
|
|
repo_format1: 'https://github.com/jimi-c/test_role'
|
|
repo_format2: 'git@github.com:jimi-c/test_role.git'
|
|
repo_format3: 'ssh://git@github.com/jimi-c/test_role.git'
|
|
repo_submodules: 'https://github.com/abadger/test_submodules.git'
|
|
repo_submodules_newer: 'https://github.com/abadger/test_submodules_newer.git'
|
|
repo_submodule1: 'https://github.com/abadger/test_submodules_subm1.git'
|
|
repo_submodule1_newer: 'https://github.com/abadger/test_submodules_subm1_newer.git'
|
|
repo_submodule2: 'https://github.com/abadger/test_submodules_subm2.git'
|
|
repo_update_url_1: 'https://github.com/ansible-test-robinro/git-test-old'
|
|
repo_update_url_2: 'https://github.com/ansible-test-robinro/git-test-new'
|
|
repo_depth_url: 'https://github.com/ansible-test-robinro/git-test-shallow-depth'
|
|
known_host_files:
|
|
- "{{ lookup('env','HOME') }}/.ssh/known_hosts"
|
|
- '/etc/ssh/ssh_known_hosts'
|
|
git_version_supporting_depth: 1.9.1
|
|
|
|
- name: clean out the output_dir
|
|
shell: rm -rf {{ output_dir }}/*
|
|
|
|
- name: verify that git is installed so this test can continue
|
|
shell: which git
|
|
|
|
- name: get git version, only newer than {{git_version_supporting_depth}} has fixed git depth
|
|
shell: git --version | grep 'git version' | sed 's/git version //'
|
|
register: git_version
|
|
|
|
- name: set dummy git config
|
|
shell: git config --global user.email "noreply@example.com"; git config --global user.name "Ansible Test Runner"
|
|
|
|
- name: create repo_dir
|
|
file: path={{repo_dir}} state=directory
|
|
|
|
#
|
|
# Test repo=https://github.com/...
|
|
#
|
|
|
|
|
|
- name: initial checkout
|
|
git: repo={{ repo_format1 }} dest={{ checkout_dir }}
|
|
register: git_result
|
|
|
|
- name: verify information about the initial clone
|
|
assert:
|
|
that:
|
|
- "'before' in git_result"
|
|
- "'after' in git_result"
|
|
- "not git_result.before"
|
|
- "git_result.changed"
|
|
|
|
- name: repeated checkout
|
|
git: repo={{ repo_format1 }} dest={{ checkout_dir }}
|
|
register: git_result2
|
|
|
|
- name: check for tags
|
|
stat: path={{ checkout_dir }}/.git/refs/tags
|
|
register: tags
|
|
|
|
- name: check for HEAD
|
|
stat: path={{ checkout_dir }}/.git/HEAD
|
|
register: head
|
|
|
|
- name: assert presence of tags/trunk/branches
|
|
assert:
|
|
that:
|
|
- "tags.stat.isdir"
|
|
- "head.stat.isreg"
|
|
|
|
- name: verify on a reclone things are marked unchanged
|
|
assert:
|
|
that:
|
|
- "not git_result2.changed"
|
|
|
|
#
|
|
# Test repo=git@github.com:/...
|
|
# Requires variable: github_ssh_private_key
|
|
#
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: remove known_host files
|
|
file: state=absent path={{ item }}
|
|
with_items: "{{known_host_files}}"
|
|
|
|
- name: checkout ssh://git@github.com repo without accept_hostkey (expected fail)
|
|
git: repo={{ repo_format2 }} dest={{ checkout_dir }}
|
|
register: git_result
|
|
ignore_errors: true
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.failed'
|
|
- 'git_result.msg == "github.com has an unknown hostkey. Set accept_hostkey to True or manually add the hostkey prior to running the git module"'
|
|
|
|
- name: checkout git@github.com repo with accept_hostkey (expected pass)
|
|
git:
|
|
repo: '{{ repo_format2 }}'
|
|
dest: '{{ checkout_dir }}'
|
|
accept_hostkey: true
|
|
key_file: '{{ github_ssh_private_key }}'
|
|
register: git_result
|
|
when: github_ssh_private_key is defined
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.changed'
|
|
when: not git_result|skipped
|
|
|
|
#
|
|
# Test repo=ssh://git@github.com/...
|
|
# Requires variable: github_ssh_private_key
|
|
#
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: checkout ssh://git@github.com repo with accept_hostkey (expected pass)
|
|
git:
|
|
repo: '{{ repo_format3 }}'
|
|
dest: '{{ checkout_dir }}'
|
|
version: 'master'
|
|
accept_hostkey: false # should already have been accepted
|
|
key_file: '{{ github_ssh_private_key }}'
|
|
register: git_result
|
|
when: github_ssh_private_key is defined
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.changed'
|
|
when: not git_result|skipped
|
|
|
|
# Test a non-updating repo query with no destination specified
|
|
|
|
- name: get info on a repo without updating and with no destination specified
|
|
git:
|
|
repo: '{{ repo_format1 }}'
|
|
update: no
|
|
clone: no
|
|
accept_hostkey: yes
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.changed'
|
|
|
|
# Test that a specific revision can be checked out
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: clone to specific revision
|
|
git:
|
|
repo: "{{ repo_format1 }}"
|
|
dest: "{{ checkout_dir }}"
|
|
version: df4612ba925fbc1b3c51cbb006f51a0443bd2ce9
|
|
|
|
- name: check HEAD after clone to revision
|
|
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.stdout == "df4612ba925fbc1b3c51cbb006f51a0443bd2ce9"'
|
|
|
|
- name: update to specific revision
|
|
git:
|
|
repo: "{{ repo_format1 }}"
|
|
dest: "{{ checkout_dir }}"
|
|
version: 4e739a34719654db7b04896966e2354e1256ea5d
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.changed'
|
|
|
|
- name: check HEAD after update to revision
|
|
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.stdout == "4e739a34719654db7b04896966e2354e1256ea5d"'
|
|
|
|
# Test a revision not available under refs/heads/ or refs/tags/
|
|
|
|
- name: attempt to get unavailable revision
|
|
git:
|
|
repo: "{{ repo_format1 }}"
|
|
dest: "{{ checkout_dir }}"
|
|
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
|
|
ignore_errors: true
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.failed'
|
|
|
|
# Same as the previous test, but this time we specify which ref
|
|
# contains the SHA1
|
|
- name: update to revision by specifying the refspec
|
|
git:
|
|
repo: https://github.com/ansible/ansible-examples.git
|
|
dest: '{{ checkout_dir }}'
|
|
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
|
|
refspec: refs/pull/7/merge
|
|
|
|
- name: check HEAD after update with refspec
|
|
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.stdout == "2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b"'
|
|
|
|
# try out combination of refspec and depth
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: update to revision by specifying the refspec with depth=1
|
|
git:
|
|
repo: https://github.com/ansible/ansible-examples.git
|
|
dest: '{{ checkout_dir }}'
|
|
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
|
|
refspec: refs/pull/7/merge
|
|
depth: 1
|
|
|
|
- name: check HEAD after update with refspec
|
|
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.stdout == "2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b"'
|
|
|
|
- name: try to access other commit
|
|
shell: git checkout 0ce1096
|
|
register: checkout_shallow
|
|
failed_when: False
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
|
|
- name: make sure the old commit was not fetched
|
|
assert:
|
|
that:
|
|
- checkout_shallow.rc == 1
|
|
- checkout_shallow|failed
|
|
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: clone to revision by specifying the refspec
|
|
git:
|
|
repo: https://github.com/ansible/ansible-examples.git
|
|
dest: '{{ checkout_dir }}'
|
|
version: 2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b
|
|
refspec: refs/pull/7/merge
|
|
|
|
- name: check HEAD after update with refspec
|
|
command: git rev-parse HEAD chdir="{{ checkout_dir }}"
|
|
register: git_result
|
|
|
|
- assert:
|
|
that:
|
|
- 'git_result.stdout == "2cfde3668b8bb10fbe2b9d5cec486025ad8cc51b"'
|
|
|
|
#
|
|
# Submodule tests
|
|
#
|
|
|
|
# Repository A with submodules defined (repo_submodules)
|
|
# .gitmodules file points to Repository I
|
|
# Repository B forked from A that has newer commits (repo_submodules_newer)
|
|
# .gitmodules file points to Repository II instead of I
|
|
# .gitmodules file also points to Repository III
|
|
# Repository I for submodule1 (repo_submodule1)
|
|
# Has 1 file checked in
|
|
# Repository II forked from I that has newer commits (repo_submodule1_newer)
|
|
# Has 2 files checked in
|
|
# Repository III for a second submodule (repo_submodule2)
|
|
# Has 1 file checked in
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: Test that clone without recursive does not retrieve submodules
|
|
git:
|
|
repo: '{{ repo_submodules }}'
|
|
dest: '{{ checkout_dir }}'
|
|
recursive: no
|
|
|
|
- command: 'ls -1a {{ checkout_dir }}/submodule1'
|
|
register: submodule1
|
|
|
|
- assert:
|
|
that: '{{ submodule1.stdout_lines|length }} == 2'
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
|
|
- name: Test that clone with recursive retrieves submodules
|
|
git:
|
|
repo: '{{ repo_submodules }}'
|
|
dest: '{{ checkout_dir }}'
|
|
recursive: yes
|
|
|
|
- command: 'ls -1a {{ checkout_dir }}/submodule1'
|
|
register: submodule1
|
|
|
|
- assert:
|
|
that: '{{ submodule1.stdout_lines|length }} == 4'
|
|
|
|
- name: Copy the checkout so we can run several different tests on it
|
|
command: 'cp -pr {{ checkout_dir }} {{ checkout_dir }}.bak'
|
|
|
|
|
|
|
|
- name: Test that update without recursive does not change submodules
|
|
command: 'git config --replace-all remote.origin.url {{ repo_submodules_newer }}'
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
|
|
- git:
|
|
repo: '{{ repo_submodules_newer }}'
|
|
dest: '{{ checkout_dir }}'
|
|
recursive: no
|
|
update: yes
|
|
track_submodules: yes
|
|
|
|
- command: 'ls -1a {{ checkout_dir }}/submodule1'
|
|
register: submodule1
|
|
|
|
- stat:
|
|
path: '{{ checkout_dir }}/submodule2'
|
|
register: submodule2
|
|
|
|
- command: 'ls -1a {{ checkout_dir }}/submodule2'
|
|
register: submodule2
|
|
|
|
- assert:
|
|
that: '{{ submodule1.stdout_lines|length }} == 4'
|
|
- assert:
|
|
that: '{{ submodule2.stdout_lines|length }} == 2'
|
|
|
|
|
|
|
|
- name: Restore checkout to prior state
|
|
file: state=absent path={{ checkout_dir }}
|
|
- command: 'cp -pr {{ checkout_dir }}.bak {{ checkout_dir }}'
|
|
|
|
- name: Test that update with recursive updated existing submodules
|
|
command: 'git config --replace-all remote.origin.url {{ repo_submodules_newer }}'
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
|
|
- git:
|
|
repo: '{{ repo_submodules_newer }}'
|
|
dest: '{{ checkout_dir }}'
|
|
update: yes
|
|
recursive: yes
|
|
track_submodules: yes
|
|
|
|
- command: 'ls -1a {{ checkout_dir }}/submodule1'
|
|
register: submodule1
|
|
|
|
- assert:
|
|
that: '{{ submodule1.stdout_lines|length }} == 5'
|
|
|
|
|
|
- name: Test that update with recursive found new submodules
|
|
command: 'ls -1a {{ checkout_dir }}/submodule2'
|
|
register: submodule2
|
|
|
|
- assert:
|
|
that: '{{ submodule2.stdout_lines|length }} == 4'
|
|
# test change of repo url
|
|
# see https://github.com/ansible/ansible-modules-core/pull/721
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: Clone example git repo
|
|
git:
|
|
repo: '{{ repo_update_url_1 }}'
|
|
dest: '{{ checkout_dir }}'
|
|
|
|
- name: Clone repo with changed url to the same place
|
|
git:
|
|
repo: '{{ repo_update_url_2 }}'
|
|
dest: '{{ checkout_dir }}'
|
|
register: clone2
|
|
|
|
- assert:
|
|
that: "clone2|success"
|
|
|
|
- name: check url updated
|
|
shell: git remote show origin | grep Fetch
|
|
register: remote_url
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
environment:
|
|
LC_ALL: C
|
|
|
|
- assert:
|
|
that:
|
|
- "'git-test-new' in remote_url.stdout"
|
|
- "'git-test-old' not in remote_url.stdout"
|
|
|
|
- name: check for new content in git-test-new
|
|
stat: path={{ checkout_dir }}/newfilename
|
|
register: repo_content
|
|
|
|
- name: assert presence of new file in repo (i.e. working copy updated)
|
|
assert:
|
|
that: "repo_content.stat.exists"
|
|
|
|
# Test that checkout by branch works when the branch is not in our current repo but the sha is
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: Clone example git repo that we're going to modify
|
|
git:
|
|
repo: '{{ repo_update_url_1 }}'
|
|
dest: '{{ checkout_dir }}/repo'
|
|
|
|
- name: Clone the repo again - this is what we test
|
|
git:
|
|
repo: '{{ checkout_dir }}/repo'
|
|
dest: '{{ checkout_dir }}/checkout'
|
|
|
|
- name: Add a branch to the repo
|
|
command: git branch new-branch
|
|
args:
|
|
chdir: '{{ checkout_dir }}/repo'
|
|
|
|
- name: Checkout the new branch in the checkout
|
|
git:
|
|
repo: '{{ checkout_dir}}/repo'
|
|
version: 'new-branch'
|
|
dest: '{{ checkout_dir }}/checkout'
|
|
|
|
|
|
# Test the depth option and fetching revisions that were ignored first
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: Clone example git repo with depth=1
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
|
|
- name: try to access earlier commit
|
|
shell: git checkout 79624b4
|
|
register: checkout_early
|
|
failed_when: False
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
|
|
- name: make sure the old commit was not fetched
|
|
assert:
|
|
that: checkout_early.rc == 1
|
|
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
|
|
|
|
# tests https://github.com/ansible/ansible/issues/14954
|
|
- name: fetch repo again with depth=1
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
register: checkout2
|
|
|
|
- assert:
|
|
that: "not checkout2|changed"
|
|
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
|
|
|
|
- name: again try to access earlier commit
|
|
shell: git checkout 79624b4
|
|
register: checkout_early
|
|
failed_when: False
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
|
|
- name: again make sure the old commit was not fetched
|
|
assert:
|
|
that: checkout_early.rc == 1
|
|
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
|
|
|
|
# make sure we are still able to fetch other versions
|
|
- name: Clone same repo with older version
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
version: earlytag
|
|
register: cloneold
|
|
|
|
- assert:
|
|
that: "cloneold|success"
|
|
|
|
- name: try to access earlier commit
|
|
shell: git checkout 79624b4
|
|
args:
|
|
chdir: '{{ checkout_dir }}'
|
|
|
|
# test for https://github.com/ansible/ansible-modules-core/issues/527
|
|
# clone a repo, add a tag to the same commit and try to checkout the new commit
|
|
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: checkout example repo
|
|
git: repo={{ repo_format1 }} dest={{ checkout_dir }}
|
|
|
|
- name: clone example repo locally
|
|
git: repo={{ checkout_dir }} dest={{checkout_dir}}.copy
|
|
|
|
- name: get tags of head
|
|
command: git tag --contains chdir="{{ checkout_dir }}.copy"
|
|
register: listoftags
|
|
|
|
- name: make sure the tag does not yet exist
|
|
assert:
|
|
that:
|
|
- "'newtag' not in listoftags.stdout_lines"
|
|
|
|
- name: add tag in orig repo
|
|
command: git tag newtag chdir="{{ checkout_dir }}"
|
|
|
|
- name: update copy with new tag
|
|
git: repo={{ checkout_dir }} dest={{checkout_dir}}.copy version=newtag
|
|
register: update_new_tag
|
|
|
|
- name: get tags of new head
|
|
command: git tag --contains chdir="{{ checkout_dir }}.copy"
|
|
register: listoftags
|
|
|
|
- name: check new head
|
|
assert:
|
|
that:
|
|
- not update_new_tag|changed
|
|
- "'newtag' in listoftags.stdout_lines"
|
|
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
|
|
# Test for https://github.com/ansible/ansible-modules-core/issues/3456
|
|
# clone a repo with depth and version specified
|
|
|
|
- name: clone repo with both version and depth specified
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
version: master
|
|
|
|
- name: run a second time (now fetch, not clone)
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
version: master
|
|
register: git_fetch
|
|
|
|
- name: ensure the fetch succeeded
|
|
assert:
|
|
that: git_fetch|success
|
|
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
- name: clone repo with both version and depth specified
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
version: master
|
|
|
|
- name: switch to older branch with depth=1 (uses fetch)
|
|
git:
|
|
repo: '{{ repo_depth_url }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
version: earlybranch
|
|
register: git_fetch
|
|
|
|
- name: ensure the fetch succeeded
|
|
assert:
|
|
that: git_fetch|success
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|
|
# test for https://github.com/ansible/ansible-modules-core/issues/3782
|
|
# make sure shallow fetch works when no version is specified
|
|
|
|
- name: prepare old git repo
|
|
shell: git init; echo "1" > a; git add a; git commit -m "1"
|
|
args:
|
|
chdir: "{{repo_dir}}"
|
|
|
|
- name: checkout old repo
|
|
git:
|
|
repo: '{{ repo_dir }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
|
|
- name: "update repo"
|
|
shell: echo "2" > a; git commit -a -m "2"
|
|
args:
|
|
chdir: "{{repo_dir}}"
|
|
|
|
- name: fetch updated repo
|
|
git:
|
|
repo: '{{ repo_dir }}'
|
|
dest: '{{ checkout_dir }}'
|
|
depth: 1
|
|
register: git_fetch
|
|
ignore_errors: yes
|
|
|
|
- name: read file
|
|
shell: cat {{ checkout_dir }}/a
|
|
|
|
- name: check update arrived
|
|
assert:
|
|
that:
|
|
- "{{ lookup('file', checkout_dir+'/a' )}} == 2"
|
|
- git_fetch|changed
|
|
|
|
- name: clear checkout_dir
|
|
file: state=absent path={{ checkout_dir }}
|
|
|