diff --git a/.travis.yml b/.travis.yml index 55c36b0..763738f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,29 @@ cache: bundler ## Script to run for the test stage script: + # yamllint disable rule:line-length + # Converge and verify the instance; `saltcheck` relies upon the `converge` as well - bin/kitchen verify "${INSTANCE}" + # If a `develop` instance, get the appropriate version of `saltcheck.py` (temporary) + # Likewise, use a custom `cron.py` temporarily until the upstream PR is merged: + # - https://github.com/saltstack/salt/pull/55016 + - if [ ! -z $(echo "${INSTANCE}" | grep \\-develop-) ]; then + bin/kitchen exec "${INSTANCE}" -c + "sudo curl -o \$(find /usr/lib/ -type d -name modules | grep packages/salt/modules)/saltcheck.py + https://raw.githubusercontent.com/myii/salt/fix/add-retcode/salt/modules/saltcheck.py"; + bin/kitchen exec "${INSTANCE}" -c + "sudo curl -o \$(find /usr/lib/ -type d -name modules | grep packages/salt/modules)/cron.py + https://raw.githubusercontent.com/myii/salt/fix/add-retcode/salt/modules/cron.py"; + fi + # If a `develop` instance, run all of the `saltcheck` tests + - if [ ! -z $(echo "${INSTANCE}" | grep \\-develop-) ]; then + bin/kitchen exec "${INSTANCE}" -c + "sudo salt-call + --config-dir=/tmp/kitchen/etc/salt + saltcheck.run_state_tests + cron check_all=True"; + fi + # yamllint enable rule:line-length ## Stages and jobs matrix stages: @@ -33,7 +55,7 @@ jobs: script: # Install and run `salt-lint` - pip install --user salt-lint - - git ls-files | grep '\.sls$\|\.jinja$\|\.j2$\|\.tmpl$' + - git ls-files | grep '\.sls$\|\.jinja$\|\.j2$\|\.tmpl$\|\.tst$' | xargs -I {} salt-lint {} # Install and run `yamllint` # Need at least `v1.17.0` for the `yaml-files` setting diff --git a/cron/config/file.sls b/cron/config/file.sls index ccc0333..2da2ae1 100644 --- a/cron/config/file.sls +++ b/cron/config/file.sls @@ -5,40 +5,21 @@ {%- set tplroot = tpldir.split('/')[0] %} {%- from tplroot ~ "/map.jinja" import cron with context %} -{%- if 'tasks' in cron %} - {%- for task,task_options in cron.tasks.items() %} +{%- for task, task_options in cron.get('tasks', {}).items() %} +{%- set cron_type = task_options.type|d('present') %} cron.{{ task }}: - cron.{{ task_options.type|default('present') }}: + cron.{{ cron_type }}: - name: {{ task_options.name }} - {%- if 'user' in task_options %} - - user: {{ task_options.user|default('root') }} - {%- endif %} - {%- if 'minute' in task_options %} - - minute: '{{ task_options.minute }}' - {%- endif %} - {%- if 'hour' in task_options %} - - hour: '{{ task_options.hour }}' - {%- endif %} - {%- if 'daymonth' in task_options %} - - daymonth: '{{ task_options.daymonth }}' - {%- endif %} - {%- if 'month' in task_options %} - - month: '{{ task_options.month }}' - {%- endif %} - {%- if 'dayweek' in task_options %} - - dayweek: '{{ task_options.dayweek }}' - {%- endif %} - {%- if 'commented' in task_options and task_options.commented %} - - commented: True - {%- endif %} - {%- if 'special' in task_options %} - - special: '{{ task_options.special }}' - {%- endif %} + - user: {{ task_options.user|d('root') }} - identifier: '{{ task }}' - {%- if 'comment' in task_options %} - - comment: {{ task_options.comment }} + {%- if cron_type == 'present' %} + - commented: {{ task_options.commented|d(False) }} + {%- for section in ['minute', 'hour', 'daymonth', 'month', 'dayweek', 'comment', 'special'] %} + {%- if section in task_options %} + - {{ section }}: '{{ task_options[section] }}' + {%- endif %} + {%- endfor %} {%- endif %} - {%- endfor %} -{%- endif %} +{%- endfor %} diff --git a/cron/saltcheck-tests/config/file.tst b/cron/saltcheck-tests/config/file.tst new file mode 100644 index 0000000..23f0a16 --- /dev/null +++ b/cron/saltcheck-tests/config/file.tst @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{%- set cron = salt['pillar.get']('cron', {}) %} + +{%- for task, task_options in cron.get('tasks', {}).items() %} +{%- set cron_type = task_options.type|d('present') %} + +validate_cron.{{ task }}_{{ cron_type }}: + module_and_function: cron.get_entry + args: + - {{ task_options.user|d('root') }} + - {{ task }} + {%- if cron_type == 'absent' %} + assertion: assertFalse + {%- else %} + assertion: assertEqual + assertion_section: identifier + expected-return: {{ task }} + {%- endif %} + +{%- if cron_type == 'present' %} +validate_cron.{{ task }}_commented: + module_and_function: cron.get_entry + args: + - {{ task_options.user|d('root') }} + - {{ task }} + assertion: {{ 'assertTrue' if task_options.commented|d(False) else 'assertFalse' }} + assertion_section: commented + +{#- Note: `special` is `spec` in the module #} +{%- for section in ['minute', 'hour', 'daymonth', 'month', 'dayweek', 'comment', 'spec'] %} +{%- if section in task_options %} +{%- set expected = task_options[section] %} +validate_cron.{{ task }}_{{ section }}: + module_and_function: cron.get_entry + args: + - {{ task_options.user|d('root') }} + - {{ task }} + assertion: {{ 'assertLessEqual' if expected == 'random' else 'assertEqual' }} + assertion_section: {{ section }} + expected-return: '{{ 0 if expected == 'random' else expected }}' +{%- endif %} +{%- endfor %} +{%- endif %} + +{%- endfor %} diff --git a/cron/saltcheck-tests/package/install.tst b/cron/saltcheck-tests/package/install.tst new file mode 100644 index 0000000..5ea2cd0 --- /dev/null +++ b/cron/saltcheck-tests/package/install.tst @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{%- set package_name = 'cronie' %} +{%- if grains.os_family in ['Debian'] %} +{%- set package_name = 'cron' %} +{%- endif %} + +verify_cron.package: + module_and_function: pkg.version + args: + - {{ package_name }} + assertion: assertNotEmpty diff --git a/cron/saltcheck-tests/service/running.tst b/cron/saltcheck-tests/service/running.tst new file mode 100644 index 0000000..cb971fd --- /dev/null +++ b/cron/saltcheck-tests/service/running.tst @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{%- set service_name = 'crond' %} +{%- if grains.os_family in ['Debian', 'Suse'] %} +{%- set service_name = 'cron' %} +{%- elif grains.os_family in ['Arch'] %} +{%- set service_name = 'cronie' %} +{%- endif %} + +verify_cron.service_available: + module_and_function: service.available + args: + - {{ service_name }} + assertion: assertTrue + +verify_cron.service_enabled: + module_and_function: service.enabled + args: + - {{ service_name }} + assertion: assertTrue + +verify_cron.service_running: + module_and_function: service.status + args: + - {{ service_name }} + assertion: assertTrue diff --git a/test/salt/pillar/cron.sls b/test/salt/pillar/cron.sls index bad5a78..d7f6a77 100644 --- a/test/salt/pillar/cron.sls +++ b/test/salt/pillar/cron.sls @@ -4,6 +4,7 @@ cron: enabled: true # Default tasks: + # Test all of the available options task1: type: present # Default name: echo test > /tmp/test @@ -14,18 +15,22 @@ cron: month: 1 dayweek: 6 comment: comment1 + commented: false + # Test `type: absent` task2: type: absent # To remove that crontask name: echo task2 > /tmp/test2 user: root minute: random hour: 1 + # Test `special` task3: - type: absent + type: present name: echo task3 > /tmp/test3 user: root special: '@hourly' comment: comment3 + # Test `*` task4: type: present # run every 5 minutes name: echo task4 > /tmp/test4 @@ -33,3 +38,11 @@ cron: minute: '*/5' hour: '*' comment: comment4 + # Test `commented: true` and `minute: random` + task5: + type: present + name: echo task5 > /tmp/test5 + user: root + minute: random + hour: 1 + commented: true