From 22ac51fe0ed2ecb7ecdd22cb2c1e740ec1534b21 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sep 28 2017 07:06:08 +0000 Subject: [PATCH 1/2] standard-test-scripts: Require listing all files to copy In this role we now require listing all files to copy. This is because often the test command isn't just a simple script, but may be a file with environment variables or arguments (eg: 'make -C /path test'). This is also for consistent arguments with the similar standard-role-chroot role. --- diff --git a/roles/standard-test-scripts/README.md b/roles/standard-test-scripts/README.md index d407bcc..1f10e66 100644 --- a/roles/standard-test-scripts/README.md +++ b/roles/standard-test-scripts/README.md @@ -12,6 +12,10 @@ test scripts and related files will be copied to the target into You should define the following variables: - * tests: An array of scripts to run - * files: A list of files or directories needed by the scripts + * tests: An array of scripts or commands to run + * files: A list of script files or needed files or directories +You can define these variables: + + * target: A target directory to place the files. Defaults to + /var/tmp/tests diff --git a/roles/standard-test-scripts/tasks/main.yml b/roles/standard-test-scripts/tasks/main.yml index bddd620..45e7fe0 100644 --- a/roles/standard-test-scripts/tasks/main.yml +++ b/roles/standard-test-scripts/tasks/main.yml @@ -5,13 +5,12 @@ - rsync when: ansible_pkg_mgr != 'unknown' -- name: Copy test scripts to target +- name: Copy test files to target synchronize: src: "{{ item }}" - dest: /var/tmp/tests/ + dest: "{{ target }}" ssh_args: "-o UserKnownHostsFile=/dev/null" with_items: - - "{{ tests }}" - "{{ files }}" - block: @@ -19,14 +18,10 @@ shell: | set -e mkdir -p /var/tmp/artifacts - logfile=/var/tmp/artifacts/test.$(echo {{ item }} | sed -e 's/\//-/g').log + logfile=/var/tmp/artifacts/test.$(basename "{{ item }}" | tr -d ' /.').log exec 2>>$logfile 1>>$logfile - cd /var/tmp/tests - if [ -x {{ item }} ]; then - ./$(basename {{ item }}) && result="PASS" || result="FAIL" - else - /bin/sh -e ./$(basename {{ item }}) && result="PASS" || result="FAIL" - fi + cd "{{ target }}" + {{ item }} && result="PASS" || result="FAIL" echo "$result {{ item }}" >> /var/tmp/artifacts/test.log with_items: - "{{ tests }}" diff --git a/roles/standard-test-scripts/vars/main.yml b/roles/standard-test-scripts/vars/main.yml index 81108ab..db518f9 100644 --- a/roles/standard-test-scripts/vars/main.yml +++ b/roles/standard-test-scripts/vars/main.yml @@ -1,3 +1,4 @@ --- -tests: [] -files: [] +tests: [ ] +files: [ ] +target: /var/tmp/tests/ From 01f220b49b7744be3abc4c949763db910de86341 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sep 28 2017 07:14:49 +0000 Subject: [PATCH 2/2] standard-test-chroot: Execute test scripts in a chroot Put this role in your tests.yml playbook and specify a number of test scripts to execute as tests. These will be executed in a prepared chroot including all the packages that are listed. The results of each script will be piped into log file in the artifacts directory. If any script exits with a non-zero exit code the role will fail. In the case of test subjects such a host or container, these test scripts and related files will be copied to the target into /var/tmp/tests before execution. You should define the following variables: * tests: An array of scripts to run * files: A list of files or directories needed by the scripts * packages: A list of packages to install in the chroot You can define these variables: * root: The path for the chroot. Defaults to /var/tmp/tests/test * target: A target directory inside the chroot to which to place the files. Defaults to /var/tmp/tests --- diff --git a/roles/standard-test-chroot/README.md b/roles/standard-test-chroot/README.md new file mode 100644 index 0000000..0631270 --- /dev/null +++ b/roles/standard-test-chroot/README.md @@ -0,0 +1,26 @@ +# Ansible role for executing test scripts in a chroot + +Put this role in your tests.yml playbook and specify a +number of test scripts to execute as tests. These will +be executed in a prepared chroot including all the packages +that are listed. + +The results of each script will be piped into log file in the +artifacts directory. If any script exits with a non-zero exit +code the role will fail. + +In the case of test subjects such a host or container, these +test scripts and related files will be copied to the target into +/var/tmp/tests before execution. + +You should define the following variables: + + * tests: An array of scripts to run + * files: A list of files or directories needed by the scripts + * packages: A list of packages to install in the chroot + +You can define these variables: + + * root: The path for the chroot. Defaults to /var/tmp/tests/test + * target: A target directory inside the chroot to which to + place the files. Defaults to /var/tmp/tests diff --git a/roles/standard-test-chroot/tasks/main.yml b/roles/standard-test-chroot/tasks/main.yml new file mode 100644 index 0000000..c98dc20 --- /dev/null +++ b/roles/standard-test-chroot/tasks/main.yml @@ -0,0 +1,95 @@ +--- +- name: Add executor host + add_host: + name: executor + ansible_connection: local + ansible_ssh_host: 127.0.0.1 + ansible_ssh_connection: local + +- block: + - name: Gather facts + setup: + delegate_facts: True + + - name: Install chroot build requirements + package: name={{ item }} state=present + with_items: + - dnf + - rsync + + - name: Perform the chroot build + shell: | + . /etc/os-release + set -eufx + cd "{{ playbook_dir }}" + rm -rf "{{ root }}" + dnf -y --installroot="{{ root }}" --releasever=$VERSION_ID install dnf fedora-release {{ packages | join(" ") }} + for path in {{ files | map("quote") | join(" ") }}; do + mkdir -p "{{ root }}/{{ target }}/$(basename $path)" + rsync -Hvax $path/./ "{{ root }}/{{ target }}/$(basename $path)/./" + done + + # Everything in the previous block is run on executor + delegate_to: executor + +- name: Create target directory + file: + path: "{{ root }}/" + state: directory + +- name: Sync the chroot into the test subject + synchronize: + dest: "{{ root }}/" + src: "{{ root }}/" + mode: push + ssh_args: "-o UserKnownHostsFile=/dev/null" + +# We run the container using a chroot because for many test containers +# --capabilities=all is not enough to get systemd-nspawn to behave +# and have tests interact properly with the kernel +- name: Prepare the chroot on the target + shell: | + set -eufx + name=$(basename {{ root }} | tr -d ' /.') + rm -rf /var/tmp/artifacts + mkdir -p /var/tmp/artifacts {{ root }}/host + logfile=/var/tmp/artifacts/$name.log + exec 2>>$logfile 1>>$logfile + setfiles -v -r {{ root }} /etc/selinux/targeted/contexts/files/file_contexts {{ root }} + mount -t proc proc {{ root }}/proc/ + mount -t sysfs sys {{ root }}/sys/ + mount -o bind /dev {{ root }}/dev + mount -t tmpfs tmpfs {{ root }}/dev/shm + mount -t devpts devpts {{ root }}/dev/pts + mount -t selinuxfs selinuxfs {{ root }}/sys/fs/selinux + mount -o bind / {{ root }}/host + cp -f /etc/hosts {{ root }}/etc/ + cp -f /etc/resolv.conf {{ root }}/etc/resolv.conf + ln -sf /proc/mounts {{ root }}/etc/mtab + +- block: + - name: Execute test scripts + shell: | + set -eufx + logfile=/var/tmp/artifacts/test.$(basename "{{ item }}" | tr -d ' /.').log + exec 2>>$logfile 1>>$logfile + chroot {{ root }} /bin/sh -c "export LC_ALL=en_US.UTF-8; cd {{ target }}; {{ item }}" && result="PASS" || result="FAIL" + echo "$result {{ item }}" >> /var/tmp/artifacts/test.log + with_items: + - "{{ tests }}" + + always: + - name: Pull out the logs + synchronize: + dest: "{{ artifacts }}/" + src: "/var/tmp/artifacts/./" + mode: pull + ssh_args: "-o UserKnownHostsFile=/dev/null" + when: artifacts|default("") != "" + + # Can't go in block. See + # https://github.com/ansible/ansible/issues/20736 + - name: Check the results + shell: grep "^FAIL" /var/tmp/artifacts/test.log + register: test_fails + failed_when: test_fails.stdout or test_fails.stderr diff --git a/roles/standard-test-chroot/vars/main.yml b/roles/standard-test-chroot/vars/main.yml new file mode 100644 index 0000000..af7228a --- /dev/null +++ b/roles/standard-test-chroot/vars/main.yml @@ -0,0 +1,6 @@ +--- +packages: [ ] +files: [ ] +tests: [ ] +target: /var/tmp/tests/ +root: /var/tmp/tests/test