From 879855ce705770834d0be8182818ae672bc72063 Mon Sep 17 00:00:00 2001 From: Stanislav Levin Date: Feb 25 2020 16:02:12 +0000 Subject: Azure: Allow to run integration tests Azure provides Microsoft-hosted agents having tasty resources [0]. For now (Feb 2020), - (Linux only) Run steps in a cgroup that offers 6 GB of physical memory and 13 GB of total memory - Provide at least 10 GB of storage for your source and build outputs. This is enough to set up IPA environments consisted of not only master but also replicas and clients and thus, run IPA integration tests. New Azure IPA tests workflow: + 1) Azure generate jobs using Matrix strategy 2) each job is run in parallel (up to 10) within its own VM (Ubuntu-18.04): a) downloads prepared Docker container image (artifact) from Azure cloud (built on Build Job) and loads the received image into local pool + b) docker-compose creates the Docker environment having a required number of replicas and/or clients + c) setup_containers.py script does the needed container's changes (DNS, SSH, etc.) + d) launch IPA tests on tests' controller e) publish tests results in JUnit format to provide a comprehensive test reporting and analytics experience via Azure WebUI [1] f) publish regular system logs as artifacts [0] https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops [1] https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/test/publish-test-results?view=azure-devops&tabs=yaml Fixes: https://pagure.io/freeipa/issue/8202 Signed-off-by: Stanislav Levin Reviewed-By: Alexander Bokovoy --- diff --git a/ipatests/azure/azure-pipelines.yml b/ipatests/azure/azure-pipelines.yml index 3ae6f46..dac3f4f 100644 --- a/ipatests/azure/azure-pipelines.yml +++ b/ipatests/azure/azure-pipelines.yml @@ -5,11 +5,17 @@ variables: CI_RUNNER_LOGS_DIR: logs localsdir: $(Build.Repository.LocalPath) builddir: /__w/1/s + # Provision script: setup_containers.py requires Python3.6+ + # Ubuntu-16.04 has Python 3.5.2 on board + # https://github.com/actions/virtual-environments/blob/master/images/linux/Ubuntu1604-README.md + # Ubuntu-18.04 - 3.6.9 + # https://github.com/actions/virtual-environments/blob/master/images/linux/Ubuntu1804-README.md + VM_IMAGE: 'Ubuntu-18.04' jobs: - job: Build pool: - vmImage: 'Ubuntu-16.04' + vmImage: $(VM_IMAGE) container: image: registry.fedoraproject.org/f31/fedora-toolbox options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged @@ -44,7 +50,7 @@ jobs: - job: Lint pool: - vmImage: 'Ubuntu-16.04' + vmImage: $(VM_IMAGE) container: image: registry.fedoraproject.org/f31/fedora-toolbox options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged @@ -63,7 +69,7 @@ jobs: - job: Tox pool: - vmImage: 'Ubuntu-16.04' + vmImage: $(VM_IMAGE) container: image: registry.fedoraproject.org/f31/fedora-toolbox options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged @@ -94,7 +100,7 @@ jobs: - job: WebUI_Unit_Tests pool: - vmImage: 'Ubuntu-16.04' + vmImage: $(VM_IMAGE) container: image: registry.fedoraproject.org/f31/fedora-toolbox options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged @@ -126,25 +132,59 @@ jobs: testRunTitle: 'Web UI unit test results' condition: succeededOrFailed() -- template: templates/test-jobs.yml - parameters: - jobName: BASE_XMLRPC - jobTitle: BASE and XMLRPC tests - testsToRun: - - test_cmdline - - test_install - - test_ipaclient - - test_ipalib - - test_ipaplatform - - test_ipapython - - test_ipaserver - - test_ipatests_plugins - - test_xmlrpc - testsToIgnore: - - test_integration - - test_webui - - test_ipapython/test_keyring.py - testsToDedicate: - - test_xmlrpc/test_dns_plugin.py - taskToRun: run-tests - tasksParallel: 3 +- job: BASE_XMLRPC + pool: + vmImage: $(VM_IMAGE) + dependsOn: Build + condition: succeeded() + strategy: + parallel: 3 + steps: + - template: templates/test-jobs.yml + parameters: + testsToRun: + - test_cmdline + - test_install + - test_ipaclient + - test_ipalib + - test_ipaplatform + - test_ipapython + - test_ipaserver + - test_ipatests_plugins + - test_xmlrpc + testsToIgnore: + - test_integration + - test_webui + - test_ipapython/test_keyring.py + testsToDedicate: + - test_xmlrpc/test_dns_plugin.py + taskToRun: run-tests + +- job: GATING + pool: + vmImage: $(VM_IMAGE) + dependsOn: Build + condition: succeeded() + strategy: + matrix: + installation_TestInstallMaster: + testsToRun: test_integration/test_installation.py::TestInstallMaster + kerberos_flags: + testsToRun: test_integration/test_kerberos_flags.py + testsClients: 1 + timeoutInMinutes: 90 + + steps: + - script: | + set -e + echo "##vso[task.setvariable variable=ntestsClients]${TESTSCLIENTS:-0}" + echo "##vso[task.setvariable variable=ntestsReplicas]${TESTSREPLICAS:-0}" + displayName: Generate variables + + - template: templates/test-jobs.yml + parameters: + taskToRun: run-integration-tests + testsToRun: "$(testsToRun)" + topology: + clients: "$(ntestsClients)" + replicas: "$(ntestsReplicas)" diff --git a/ipatests/azure/azure-run-integration-tests.sh b/ipatests/azure/azure-run-integration-tests.sh new file mode 100755 index 0000000..55933a8 --- /dev/null +++ b/ipatests/azure/azure-run-integration-tests.sh @@ -0,0 +1,32 @@ +#!/bin/bash -ex + +# Normalize spacing and expand the list afterwards. Remove {} for the single list element case +tests_to_run=$(eval "echo {$(echo $TESTS_TO_RUN | sed -e 's/[ \t]+*/,/g')}" | tr -d '{}') +tests_to_ignore= +[[ -n "$TESTS_TO_IGNORE" ]] && \ +tests_to_ignore=$(eval "echo --ignore\ {$(echo $TESTS_TO_IGNORE | sed -e 's/[ \t]+*/,/g')}" | tr -d '{}') +tests_to_dedicate= +[[ -n "$TESTS_TO_DEDICATE" ]] && \ +tests_to_dedicate=$(eval "echo --slice-dedicated={$(echo $TESTS_TO_DEDICATE | sed -e 's/[ \t]+*/,/g')}" | tr -d '{}') + +tests_dir="/freeipa/$CI_RUNNER_LOGS_DIR" +mkdir -p "$tests_dir" +cd "$tests_dir" + +export IPATEST_YAML_CONFIG=~/.ipa/ipa-test-config.yaml + +echo "Run IPA tests" +ipa-run-tests \ + ${tests_to_ignore} \ + ${tests_to_dedicate} \ + --slices=${SYSTEM_TOTALJOBSINPHASE:-1} \ + --slice-num=${SYSTEM_JOBPOSITIONINPHASE:-1} \ + --logging-level=debug \ + --logfile-dir="$tests_dir" \ + --verbose --with-xunit ${tests_to_run} + +tests_result=$? +find "$tests_dir" -mindepth 1 -maxdepth 1 -not -name '.*' -type d \ + -exec tar --remove-files -czf {}.tar.gz {} \; + +exit $tests_result diff --git a/ipatests/azure/azure-run-tests.sh b/ipatests/azure/azure-run-tests.sh index f1982ab..734166b 100755 --- a/ipatests/azure/azure-run-tests.sh +++ b/ipatests/azure/azure-run-tests.sh @@ -1,11 +1,7 @@ #!/bin/bash -ex -# Setup DNS -echo -e '127.0.0.1 localhost\n::1 localhost\n' > /etc/hosts -echo 'nameserver 8.8.8.8' > /etc/resolv.conf - -server_realm=EXAMPLE.TEST -server_domain=example.test +server_realm=IPA.TEST +server_domain=ipa.test server_password=Secret123 # Normalize spacing and expand the list afterwards. Remove {} for the single list element case @@ -79,7 +75,7 @@ fi echo "Collect the logs" journalctl -b --no-pager > systemd_journal.log -tar --ignore-failed-read -cvf var_log.tar \ +tar --ignore-failed-read -czf var_log.tar.gz \ /var/log/dirsrv \ /var/log/httpd \ /var/log/ipa* \ diff --git a/ipatests/azure/docker-compose.yml b/ipatests/azure/docker-compose.yml new file mode 100644 index 0000000..e077db2 --- /dev/null +++ b/ipatests/azure/docker-compose.yml @@ -0,0 +1,55 @@ +version: '2.1' +services: + master: + image: ${IPA_DOCKER_IMAGE} + build: . + cap_add: + - ALL + security_opt: + - apparmor:unconfined + mem_limit: 1610612736 + volumes: + - /sys/fs/cgroup/systemd:/sys/fs/cgroup/systemd + - ./ipa-test-config.yaml:/root/.ipa/ipa-test-config.yaml:ro + - ${BUILD_REPOSITORY_LOCALPATH}:/freeipa + + networks: + - ${IPA_NETWORK} + + replica: + image: ${IPA_DOCKER_IMAGE} + build: . + cap_add: + - ALL + security_opt: + - apparmor:unconfined + mem_limit: 1610612736 + volumes: + - /sys/fs/cgroup/systemd:/sys/fs/cgroup/systemd + networks: + - ${IPA_NETWORK} + + client: + image: ${IPA_DOCKER_IMAGE} + build: . + cap_add: + - ALL + security_opt: + - apparmor:unconfined + mem_limit: 536870912 + volumes: + - /sys/fs/cgroup/systemd:/sys/fs/cgroup/systemd + # nfs server + - ./exports:/exports + - /lib/modules:/lib/modules:ro + networks: + - ${IPA_NETWORK} + +networks: + ipanet: + driver: bridge + enable_ipv6: true + ipam: + driver: default + config: + - subnet: ${IPA_IPV6_SUBNET} diff --git a/ipatests/azure/setup_containers.py b/ipatests/azure/setup_containers.py new file mode 100644 index 0000000..adedcc1 --- /dev/null +++ b/ipatests/azure/setup_containers.py @@ -0,0 +1,288 @@ +import logging +import os +import subprocess + +import docker +from jinja2 import Template + +logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') + +IPA_CLIENT_NUM = int(os.environ.get('IPA_CLIENT_NUM', 0)) +IPA_REPLICA_NUM = int(os.environ.get('IPA_REPLICA_NUM', 0)) +IPA_CONT_PREFIX = os.environ.get('IPA_CONT_PREFIX', '1') +IPA_TEST_DOMAIN = os.environ.get('IPA_TEST_DOMAIN', 'ipa.test') +IPA_SSH_PRIV_KEY = os.environ.get('IPA_SSH_PRIV_KEY', '/root/.ssh/id_rsa') +IPA_DNS_FORWARDER = os.environ.get('IPA_DNS_FORWARDER', '8.8.8.8') +IPA_NETWORK = os.environ.get('IPA_NETWORK', 'ipanet') +IPA_CONTROLLER = os.environ.get('IPA_CONTROLLER', 'master') + +CONTAINER_DIR = "container_{}".format(IPA_CONT_PREFIX) +IPA_TEST_CONFIG = "ipa-test-config.yaml" + + +class Container: + """ + Represents group of Docker container + """ + def __init__(self, role, dns=IPA_DNS_FORWARDER, num=1, + prefix=IPA_CONT_PREFIX, domain=IPA_TEST_DOMAIN): + self.role = role + self.num = num + self.prefix = prefix + self.dns = dns + self.domain = domain + self.dclient = docker.from_env() + + @property + def hostnames(self): + """ + hostnames of containers within group + """ + if not hasattr(self, '_hostnames'): + self._hostnames = ['{}{}.{}'.format(self.role, c, self.domain) + for c in range(1, self.num + 1)] + return self._hostnames + + @property + def names(self): + """ + names of containers within group + """ + if not hasattr(self, '_names'): + self._names = ['{}_{}_{}'.format(self.prefix, self.role, c) + for c in range(1, self.num + 1)] + return self._names + + def ip(self, name): + """ + ipv4 address of container + """ + ipanet = '{}_{}'.format(IPA_CONT_PREFIX, IPA_NETWORK) + dcont = self.dclient.containers.get(name) + return dcont.attrs['NetworkSettings']['Networks'][ipanet]['IPAddress'] + + @property + def ips(self): + """ + ipv4 addresses of containers within group + """ + if not hasattr(self, '_ips'): + self._ips = [self.ip(n) for n in self.names] + return self._ips + + def umount_docker_resource(self, path): + """ + Umount resource by its path + """ + cmd = [ + "/bin/umount", path + ] + self.execute_all(cmd) + + cmd = [ + "/bin/chmod", + "a-x", + path, + ] + self.execute_all(cmd) + + def execute(self, name, args): + """ + Exec an arbitrary command within container + """ + dcont = self.dclient.containers.get(name) + logging.info("%s: run: %s", dcont.name, args) + result = dcont.exec_run(args, demux=True) + if result.output[0] is not None: + logging.info("%s: %s", dcont.name, result.output[0]) + logging.info("%s: result: %s", dcont.name, result.exit_code) + if result.exit_code: + logging.error("stderr: %s", result.output[1].decode()) + raise subprocess.CalledProcessError( + result.exit_code, args, + result.output[1] + ) + return result + + def execute_all(self, args): + """ + Exec an arbitrary command within every container of group + """ + results = [] + for n in self.names: + results.append(self.execute(n, args)) + return results + + def add_ssh_pubkey(self, key): + """ + Add ssh public key into every container of group + """ + home_ssh_dir = "/root/.ssh" + auth_keys = os.path.join(home_ssh_dir, "authorized_keys") + cmd = [ + "/bin/bash", "-c", + (f"mkdir {home_ssh_dir} " + f"; chmod 0700 {home_ssh_dir} " + f"&& touch {auth_keys} " + f"&& chmod 0600 {auth_keys} " + f"&& echo {key} >> {auth_keys}" + ) + ] + self.execute_all(cmd) + + def setup_hosts(self): + """ + Overwrite hosts within every container of group + """ + self.umount_docker_resource("/etc/hosts") + for n, i, h in zip(self.names, self.ips, self.hostnames): + hosts = "127.0.0.1 localhost\n::1 localhost\n{ip} {host}".format( + ip=i, host=h, + ) + cmd = [ + "/bin/bash", "-c", + "echo -e '{hosts}' > /etc/hosts".format(hosts=hosts), + ] + self.execute(name=n, args=cmd) + + def setup_hostname(self): + self.umount_docker_resource("/etc/hostname") + for n, h in zip(self.names, self.hostnames): + cmd = [ + "/bin/bash", "-c", + "echo -e '{hostname}' > /etc/hostname".format(hostname=h), + ] + self.execute(name=n, args=cmd) + + cmd = [ + "hostnamectl", + "set-hostname", h, + ] + self.execute(name=n, args=cmd) + + def setup_resolvconf(self): + """ + Overwrite resolv conf within every container of group + """ + self.umount_docker_resource("/etc/resolv.conf") + ns = "nameserver {dns}".format(dns=self.dns) + cmd = [ + "/bin/bash", "-c", + "echo {ns} > /etc/resolv.conf".format(ns=ns), + ] + self.execute_all(cmd) + + +class Controller(Container): + """ + Manages groups of containers + """ + def __init__(self, contr_type=IPA_CONTROLLER): + self.containers = [] + self.contr_type = contr_type + if self.contr_type == 'master': + self.master = None + + def append(self, container): + self.containers.append(container) + + def setup_ssh(self): + """ + Generate ssh key pair and copy public part to all containers + """ + cmd = ["rm", "-f", IPA_SSH_PRIV_KEY] + self.execute(args=cmd) + + cmd = [ + "ssh-keygen", "-q", + "-f", IPA_SSH_PRIV_KEY, + "-t", "rsa", + "-m", "PEM", + "-N", "", + ] + self.execute(args=cmd) + + cmd = ["/bin/bash", "-c", "cat {}.pub".format(IPA_SSH_PRIV_KEY)] + key = self.execute(cmd).output[0].decode().rstrip() + for container in self.containers: + container.add_ssh_pubkey(key) + + def execute(self, args): + """ + Execute a command on controller (either master or local machine) + """ + if self.contr_type == 'master': + if self.master is None: + for container in self.containers: + if container.role == "master": + self.master = container + break + return self.master.execute(name=master.names[0], args=args) + + proc = subprocess.run(args, check=True, capture_output=True) + return [proc.stdout.decode().rstrip().strip("'")] + + def setup_hosts(self): + """ + Overwrite Docker's hosts + """ + hosts = [] + for container in self.containers: + container.setup_hosts() + for i, h in zip(container.ips, container.hostnames): + hosts.append("{} {}".format(i, h)) + + cmd = [ + "/bin/bash", "-c", + "echo -e '{hosts}' >> /etc/hosts".format(hosts='\n'.join(hosts)), + ] + self.execute(cmd) + + def setup_hostname(self): + """ + Overwrite Docker's hostname + """ + for container in self.containers: + container.setup_hostname() + + def setup_resolvconf(self): + """ + Overwrite Docker's embedded DNS ns + """ + for container in self.containers: + container.setup_resolvconf() + + def generate_ipa_test_config(self, config): + template = 'ipa-test-config-template.yaml' + with open(os.path.join('./templates', template), 'r') as f: + template = Template(f.read(), trim_blocks=True, lstrip_blocks=True) + + print(template.render(config)) + + with open(os.path.join(CONTAINER_DIR, IPA_TEST_CONFIG), 'w') as f: + f.write(template.render(config)) + + +controller = Controller() +master = Container(role='master') +clients = Container(role='client', num=IPA_CLIENT_NUM, dns=master.ips[0]) +replicas = Container(role='replica', num=IPA_REPLICA_NUM, dns=master.ips[0]) + +controller.append(master) +controller.append(clients) +controller.append(replicas) + +controller.setup_ssh() +controller.setup_hosts() +controller.setup_hostname() +controller.setup_resolvconf() + +config = { + 'dns_forwarder': IPA_DNS_FORWARDER, + 'ssh_private_key': IPA_SSH_PRIV_KEY, + 'domain_name': IPA_TEST_DOMAIN, + 'master': master.ips, + 'replicas': replicas.ips, + 'clients': clients.ips, +} +controller.generate_ipa_test_config(config) diff --git a/ipatests/azure/templates/ipa-test-config-template.yaml b/ipatests/azure/templates/ipa-test-config-template.yaml new file mode 100644 index 0000000..5b975b1 --- /dev/null +++ b/ipatests/azure/templates/ipa-test-config-template.yaml @@ -0,0 +1,28 @@ +admin_name: admin +admin_password: Secret123 +debug: false +dirman_dn: cn=Directory Manager +dirman_password: Secret123 +domain_level: 1 +dns_forwarder: {{ dns_forwarder }} +root_ssh_key_filename: {{ ssh_private_key }} +domains: +- name: {{ domain_name }} + type: IPA + hosts: + - external_hostname: master1.{{ domain_name }} + name: master1.{{ domain_name }} + ip: {{ master[0] }} + role: master +{% for repl_ip in replicas: %} + - external_hostname: replica{{ loop.index }}.{{ domain_name }} + name: replica{{ loop.index }}.{{ domain_name }} + ip: {{ repl_ip }} + role: replica +{% endfor %} +{% for client_ip in clients: %} + - external_hostname: client{{ loop.index }}.{{ domain_name }} + name: client{{ loop.index }}.{{ domain_name }} + ip: {{ client_ip }} + role: client +{% endfor %} diff --git a/ipatests/azure/templates/run-test.yml b/ipatests/azure/templates/run-test.yml index 301115f..7e0991f 100644 --- a/ipatests/azure/templates/run-test.yml +++ b/ipatests/azure/templates/run-test.yml @@ -1,6 +1,4 @@ parameters: - imageName: 'freeipa-fedora-builder:latest' - containerName: 'container' logsPath: 'logs' taskToRun: 'run-tests' testsToRun: '' @@ -10,24 +8,32 @@ parameters: steps: - script: | set -e - cnt=`docker create --hostname ipa.example.test --privileged -v $(Build.Repository.LocalPath):/freeipa -t ${{parameters.imageName}} /usr/sbin/init` - echo "##vso[task.setvariable variable=containerName;isOutput=true]$cnt" - name: createContainer - displayName: Create container for running a test -- script: | - set -e - docker start $(createContainer.containerName) - docker inspect $(createContainer.containerName) - displayName: Start container for running a test -- script: | - set -e - docker exec --env TESTS_TO_RUN="${{ parameters.testsToRun }}" \ - --env TESTS_TO_IGNORE="${{ parameters.testsToIgnore }}" \ - --env TESTS_TO_DEDICATE="${{ parameters.testsToDedicate }}" \ - --env CI_RUNNER_LOGS_DIR="${{ parameters.logsPath }}" \ - --env SYSTEM_TOTALJOBSINPHASE=$(System.TotalJobsInPhase) \ - --env SYSTEM_JOBPOSITIONINPHASE=$(System.JobPositionInPhase) \ - --privileged -t \ - $(createContainer.containerName) \ - /bin/bash --noprofile --norc -x /freeipa/ipatests/azure/azure-${{parameters.taskToRun}}.sh + case "$SYSTEM_PARALLELEXECUTIONTYPE" in + # slicing + "MultiMachine" ) + + TOTALJOBSINPHASE="$(System.TotalJobsInPhase)" + JOBPOSITIONINPHASE="$(System.JobPositionInPhase)" + ;; + + * ) + # matrix job's strategy also sets these variables + # MultiConfiguration + TOTALJOBSINPHASE= + JOBPOSITIONINPHASE= + ;; + esac + + project="1" + docker exec \ + --env TESTS_TO_RUN="${{ parameters.testsToRun }}" \ + --env TESTS_TO_IGNORE="${{ parameters.testsToIgnore }}" \ + --env TESTS_TO_DEDICATE="${{ parameters.testsToDedicate }}" \ + --env CI_RUNNER_LOGS_DIR="${{ parameters.logsPath }}" \ + --env SYSTEM_TOTALJOBSINPHASE="$TOTALJOBSINPHASE" \ + --env SYSTEM_JOBPOSITIONINPHASE="$JOBPOSITIONINPHASE" \ + -t \ + "${project}"_master_1 \ + /bin/bash --noprofile --norc \ + -x /freeipa/ipatests/azure/azure-${{parameters.taskToRun}}.sh displayName: Run test diff --git a/ipatests/azure/templates/setup-test-environment.yml b/ipatests/azure/templates/setup-test-environment.yml index 562a41d..1b9b5e0 100644 --- a/ipatests/azure/templates/setup-test-environment.yml +++ b/ipatests/azure/templates/setup-test-environment.yml @@ -1,3 +1,9 @@ +parameters: + imageName: 'freeipa-fedora-builder:latest' + topology: + replicas: 0 + clients: 0 + steps: - script: | set -e @@ -7,6 +13,8 @@ steps: sudo chown root:root /etc/docker/daemon.json sudo systemctl restart docker sudo modprobe ip6_tables + sudo modprobe {nfs,nfsd} + python3 -m pip install docker --user displayName: Configure containerization to allow IPv6 network - task: DownloadPipelineArtifact@0 displayName: Download prebuilt packages @@ -24,3 +32,30 @@ steps: docker images docker inspect freeipa-fedora-builder:latest displayName: Import pre-built container to the engine +- script: | + set -ex + project="1" + cont_dirname="container_$project" + rm -rf "$cont_dirname" + mkdir -p "$cont_dirname"/exports + ln -sfr ipatests/azure/docker-compose.yml "$cont_dirname"/ + touch "$cont_dirname"/ipa-test-config.yaml + cd "$cont_dirname" + export IPA_DOCKER_IMAGE="${{ parameters.imageName }}" + export IPA_NETWORK=ipanet + export IPA_IPV6_SUBNET="2001:db8:1:$project::/64" + docker-compose -p "$project" up -d \ + --scale replica="${{ parameters.topology.replicas }}" \ + --scale client="${{ parameters.topology.clients }}" \ + --force-recreate --remove-orphans + displayName: Create and start container(s) for running tests +- script: | + set -ex + ln -sfr ipatests/azure/templates ./ + ln -sfr ipatests/azure/setup_containers.py ./ + project="1" + export IPA_CONT_PREFIX="$project" + export IPA_CLIENT_NUM="${{ parameters.topology.clients }}" + export IPA_REPLICA_NUM="${{ parameters.topology.replicas }}" + python3 setup_containers.py + displayName: Setup container(s) for running tests diff --git a/ipatests/azure/templates/test-jobs.yml b/ipatests/azure/templates/test-jobs.yml index 9e93886..a75daf5 100644 --- a/ipatests/azure/templates/test-jobs.yml +++ b/ipatests/azure/templates/test-jobs.yml @@ -1,36 +1,40 @@ parameters: - jobName: '' - jobTitle: '' testsToIgnore: [] testsToRun: [] testsToDedicate: [] taskToRun: '' - tasksParallel: 1 + topology: + replicas: 0 + clients: 0 -jobs: -- job: ${{ parameters.jobName }} - displayName: ${{ parameters.jobTitle }} - dependsOn: Build - condition: succeeded() - pool: - vmImage: 'Ubuntu-16.04' - strategy: - parallel: ${{ parameters.tasksParallel }} - steps: - - template: setup-test-environment.yml - - template: run-test.yml - parameters: - containerName: 'freeipa-fedora-builder:latest' - logsPath: $(CI_RUNNER_LOGS_DIR) - taskToRun: ${{ parameters.taskToRun}} - testsToRun: ${{ join(' ', parameters.testsToRun ) }} - testsToIgnore: ${{ join(' ', parameters.testsToIgnore ) }} - testsToDedicate: ${{ join(' ', parameters.testsToDedicate ) }} - - task: PublishTestResults@2 - inputs: - testResultsFiles: $(CI_RUNNER_LOGS_DIR)/nosetests.xml - testRunTitle: ${{parameters.jobTitle}} results - condition: succeededOrFailed() - - template: save-test-artifacts.yml - parameters: - logsArtifact: logs-${{parameters.jobName}}-$(Build.BuildId)-$(System.StageAttempt)-$(System.PhaseAttempt)-$(System.JobPositionInPhase)-$(Agent.OS)-$(Agent.OSArchitecture) +steps: +- script: | + set -e + env + printf "Available entropy: %s\n" $(cat /proc/sys/kernel/random/entropy_avail) + sudo apt-get install -y rng-tools + sudo service rng-tools start + sleep 3 + printf "Available entropy: %s\n" $(cat /proc/sys/kernel/random/entropy_avail) + displayName: Increase entropy level +- template: setup-test-environment.yml + parameters: + containerName: 'freeipa-fedora-builder:latest' + topology: + replicas: ${{ parameters.topology.replicas }} + clients: ${{ parameters.topology.clients }} +- template: run-test.yml + parameters: + logsPath: $(CI_RUNNER_LOGS_DIR) + taskToRun: ${{ parameters.taskToRun }} + testsToRun: ${{ join(' ', parameters.testsToRun ) }} + testsToIgnore: ${{ join(' ', parameters.testsToIgnore ) }} + testsToDedicate: ${{ join(' ', parameters.testsToDedicate ) }} +- task: PublishTestResults@2 + inputs: + testResultsFiles: $(CI_RUNNER_LOGS_DIR)/nosetests.xml + testRunTitle: $(System.JobIdentifier) results + condition: succeededOrFailed() +- template: save-test-artifacts.yml + parameters: + logsArtifact: logs-$(System.JobIdentifier)-$(Build.BuildId)-$(System.StageAttempt)-$(System.PhaseAttempt)-$(System.JobPositionInPhase)-$(Agent.OS)-$(Agent.OSArchitecture) diff --git a/ipatests/conftest.py b/ipatests/conftest.py index 4d294f0..4105c0b 100644 --- a/ipatests/conftest.py +++ b/ipatests/conftest.py @@ -57,6 +57,7 @@ NO_RECURSE_DIRS = [ 'install/share', # integration plugin imports from ipaplatform 'ipatests/pytest_ipa', + 'ipatests/azure', ]