Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add first saltcheck tests #4

Merged
merged 29 commits into from
Oct 23, 2019
Merged

Conversation

mchugh19
Copy link

@mchugh19 mchugh19 commented Apr 8, 2019

As mentioned in
saltstack-formulas/template-formula#87

First draft at adding saltcheck tests. Uses functionality from saltcheck module from Neon as well as saltstack/salt#52441 patch to cron module. Without the cron module patch functionality, the service and install tests function, but the return from cron.ls isn't very parsible.

Given a pillar:

cron:
  enabled: True      # Default
  tasks:
    task1:
      type: present  # Default
      name: echo test > /tmp/test
      user: root
      minute: 0
      hour: 0
      daymonth: 7
      month: 1
      dayweek: 6
      comment: comment1
    task2:
      type: absent
      name: echo task2 > /tmp/test2
      user: root
      minute: random
      hour: 1

With an existing crontab of

# crontab -l
# Lines below here are managed by Salt, do not edit
# comment1 SALT_CRON_IDENTIFIER:task1
0 0 8 1 6 echo test > /tmp/test

# salt-call cron.ls root
local:
    ----------
    crons:
        |_
          ----------
          cmd:
              echo test > /tmp/test
          comment:
              comment1
          commented:
              False
          daymonth:
              8
          dayweek:
              6
          hour:
              0
          identifier:
              task1
          minute:
              0
          month:
              1
    env:
    pre:
    special:

NOTE: I've manually edited the cron entry's "daymonth" from 7 to 8

# salt-call saltcheck.run_state_tests cron check_all=True
[WARNING ] The 'environment' minion config option has been renamed to 'saltenv'. Using base as the 'saltenv' config value.
local:
    |_
      ----------
      cron:
          ----------
          verify_cron.install:
              ----------
              duration:
                  1.5572
              status:
                  Pass
          validate_cron.task1_hour:
              ----------
              duration:
                  0.0769
              status:
                  Pass
          validate_cron.task2_absent:
              ----------
              duration:
                  0.0464
              status:
                  Pass
          validate_cron.task1_month:
              ----------
              duration:
                  0.0439
              status:
                  Pass
          validate_cron.task1_daymonth:
              ----------
              duration:
                  0.0526
              status:
                  Fail: 7 is not equal to 8
          validate_cron.task1_minute:
              ----------
              duration:
                  0.0532
              status:
                  Pass
          validate_cron.task1_comment:
              ----------
              duration:
                  0.0487
              status:
                  Pass
          validate_cron.task1_dayweek:
              ----------
              duration:
                  0.0527
              status:
                  Pass
          validate_cron.task1_exists:
              ----------
              duration:
                  0.0467
              status:
                  Pass
          test_cron_service_enabled:
              ----------
              duration:
                  1.4451
              status:
                  Pass
          test_cron_service_running:
              ----------
              duration:
                  0.4851
              status:
                  Pass
    |_
      ----------
      TEST RESULTS:
          ----------
          Execution Time:
              3.9085
          Failed:
              1
          Missing Tests:
              0
          Passed:
              10
          Skipped:
              0

As shown above, all tst files in the saltcheck-tests directory can be run with:
salt-call saltcheck.run_state_tests cron check_all=True

Or individual test files can be run:
# salt-call saltcheck.run_state_tests cron.install

If this is run on a minion which has the cron module defined in top.sls as part of highstate, then tests can be run for all highstate associated states with:
# salt-call saltcheck.run_highstate_tests

Also, like all salt commands, output can be displayed as json for better parsing:

# salt-call saltcheck.run_state_tests cron check_all=True --output json
[WARNING ] The 'environment' minion config option has been renamed to 'saltenv'. Using base as the 'saltenv' config value.
{
    "local": [
        {
            "cron": {
                "validate_cron.task1_hour": {
                    "status": "Pass",
                    "duration": 0.0734
                },
                "test_cron_service_enabled": {
                    "status": "Pass",
                    "duration": 1.4594
                },
                "validate_cron.task2_absent": {
                    "status": "Pass",
                    "duration": 0.0487
                },
                "validate_cron.task1_comment": {
                    "status": "Pass",
                    "duration": 0.049
                },
                "test_cron_service_running": {
                    "status": "Pass",
                    "duration": 0.4853
                },
                "validate_cron.task1_month": {
                    "status": "Pass",
                    "duration": 0.0424
                },
                "validate_cron.task1_daymonth": {
                    "status": "Fail: 7 is not equal to 8",
                    "duration": 0.0485
                },
                "validate_cron.task1_minute": {
                    "status": "Pass",
                    "duration": 0.0488
                },
                "verify_cron.install": {
                    "status": "Pass",
                    "duration": 1.5029
                },
                "validate_cron.task1_dayweek": {
                    "status": "Pass",
                    "duration": 0.0484
                },
                "validate_cron.task1_exists": {
                    "status": "Pass",
                    "duration": 0.0508
                }
            }
        },
        {
            "TEST RESULTS": {
                "Failed": 1,
                "Missing Tests": 0,
                "Skipped": 0,
                "Passed": 10,
                "Execution Time": 3.8576
            }
        }
    ]
}

@mchugh19
Copy link
Author

mchugh19 commented Apr 8, 2019

By defining saltcheck tests in upstream formulas, it can be used as part of the forumula's CI pipeline, but also gives users of the formula the ability to validate deployed environments as well. So rather than needing to run a possibly heavyweight state.sls cron test=True and parse output for changes, you could also run saltcheck and see if there's a config gap.

@aboe76 aboe76 requested a review from myii September 1, 2019 19:06
@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 Following on from the updated discussions in saltstack-formulas/template-formula#88, I've tested the various modifications required to get this all working as well. It would be even nicer if we could get relative imports working.

Copy link
Member

@myii myii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't working as-is, so shouldn't be merged until the necessary changes have been made.

@mchugh19
Copy link
Author

mchugh19 commented Oct 14, 2019

It would be even nicer if we could get relative imports working.

If I'm following correctly, I think the issue with relative imports is needing map files or other includes copied over to the minion in order to fully render. This should be properly fixed in saltstack/salt#53068 which should be in neon.

@myii are you able to test with this version to see if it fixes your issues? https://raw.githubusercontent.com/saltstack/salt/2088199f0714fc0bff416ba11497371cdb993a3b/salt/modules/saltcheck.py

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 Since we're running develop, the current tests have been done with:

I'll test this version and let you know how it gets on.

@mchugh19
Copy link
Author

Unfortunately, I think develop does not yet include the PR mentioned which reworks how files are copied and render dependencies pulled in. Worst case, you should be able to wait a couple of weeks (fingers crossed!) for the backlog of PRs to be merged in.

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 Not a problem, worst case I can pull in the file during the Travis run. I've already been testing that when making modifications to it, such as dealing with the missing error code. I'm testing it now, so I should have a response for you fairly soon.

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 OK, making progress but I'm at the stage of figuring out how to run the tests. This was working fine up to now:

$ sudo salt-call --config-dir=/tmp/kitchen/etc/salt saltcheck.run_state_tests cron check_all=True

That still works with the old file but not the new. It reports as Missing Tests.

@myii
Copy link
Member

myii commented Oct 14, 2019

Right, so it's looking in different locations to what I expected:

looking in %s to cache tests salt://cron/package/install/saltcheck-tests
looking in %s to cache tests salt://cron/package/saltcheck-tests  
looking in %s to cache tests salt://cron/service/running/saltcheck-tests
looking in %s to cache tests salt://cron/service/saltcheck-tests
  • It's not picking up salt://cron/config/..., either.
  • Let alone salt://cron/....

The original location (with the file from develop) is:

searching path: %s /tmp/kitchen/var/cache/salt/minion/files/base  
Found test: %s /tmp/kitchen/var/cache/salt/minion/files/base/cron/saltcheck-tests/config.tst
Found test: %s /tmp/kitchen/var/cache/salt/minion/files/base/cron/saltcheck-tests/service.tst
Found test: %s /tmp/kitchen/var/cache/salt/minion/files/base/cron/saltcheck-tests/install.tst

@mchugh19
Copy link
Author

mchugh19 commented Oct 14, 2019 via email

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 So I've adjusted the location of the tests for the time being, noting that:

The saltcheck-tests folder can be customized using the saltcheck_test_location minion configuration setting.

The important thing is that it appears to be working with relative imports in map.jinja. That's a great result. It still isn't sending through an appropriate exit code, as I've mentioned here:

I'm going to try to put this all together now to form a final solution to be implemented here. Thanks for linking me to the updated file! That'll make a significant difference.

@myii
Copy link
Member

myii commented Oct 14, 2019

OK, there's a bug surprising method present in determining the path.

$ sudo salt-call --config-dir=/tmp/kitchen/etc/salt config.get saltcheck_test_location
local:
    tests/integration/saltcheck
$ sudo salt-call --config-dir=/tmp/kitchen/etc/salt saltcheck.run_state_tests cron check_all=True
looking in %s to cache tests salt://cron/package/install/tests/integration/saltcheck
looking in %s to cache tests salt://cron/package/tests/integration/saltcheck
looking in %s to cache tests salt://cron/service/running/tests/integration/saltcheck
looking in %s to cache tests salt://cron/service/tests/integration/saltcheck

My expectation for that configuration would be: salt://cron/tests/integration/saltcheck.

@mchugh19
Copy link
Author

OK, there's a bug surprising method present in determining the path.

@myii Can you try this untested version? https://gist.github.com/mchugh19/340874466f0799348b1c0be1ee022490

It should better handle your salt://state_root/saltcheck_test_location use-case.

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 OK, I will do. I've got it working with the current version but it's only running the tests for cron.package.

Called using:

sudo salt-call --config-dir=/tmp/kitchen/etc/salt saltcheck.run_state_tests cron check_all=True

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 Following on from the previous comment, it looks like it stops searching for paths when it finds the first one, that's why the rest of the tests aren't found.

https://travis-ci.org/myii/cron-formula/jobs/597872502#L2426-L2427

       looking in %s to cache tests salt://cron/package/install/saltcheck-tests
       looking in %s to cache tests salt://cron/package/saltcheck-tests

@mchugh19
Copy link
Author

it stops searching for paths when it finds the first one

That was the intent that you would have a saltcheck-tests directory at the root of your state. What file structure are you using?

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 That comment was referring to the version from neon that you linked to earlier. For that, I put a saltcheck-tests directory under each sub-directory, with the tests split accordingly, i.e.

salt://cron/config/saltcheck-tests
salt://cron/package/saltcheck-tests
salt://cron/service/saltcheck-tests

I'm now in the process of checking the one from the GitHub gist.

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 Looking promising.

https://travis-ci.org/myii/cron-formula/jobs/597878982#L2230-L2232

       looking in %s to cache tests salt://cron/package/install/saltcheck-tests
       looking in %s to cache tests salt://cron/package/saltcheck-tests
       looking in %s to cache tests salt://cron/saltcheck-tests

Still not running the cron.config tests. I suspect this is because the test pillar isn't coming through properly, which was working with the original version of saltcheck.py. I'm going to have to do some local testing to confirm that.

@myii
Copy link
Member

myii commented Oct 14, 2019

@mchugh19 OK, finally figured it out. These new versions are still not working with the tpldata values.

looking in %s to cache tests salt://cron/saltcheck-tests
[ERROR   ] tplroot
.
[ERROR   ] tplfile

[ERROR   ] tpldir
.
[ERROR   ] tpldot

[ERROR   ] slspath

This means the pillar doesn't get merged, which is why the config tests aren't being loaded:

https://github.com/saltstack-formulas/cron-formula/pull/4/files#diff-7df4435e3dd75cc6c438b17227fc6955R3

{%- if 'tasks' in cron_settings %}
  • tasks are merged in from the pillar.

So I'll stick with a local map.jinja with non-relative imports, like I had it working earlier. I'll figure out the version of saltcheck.py to use as well. When I have it ready, I'll let you know. Thanks for the feedback.

@myii
Copy link
Member

myii commented Oct 15, 2019

@mchugh19 I've got a final solution for this: https://travis-ci.org/myii/cron-formula/builds/597973852. Are you OK with me appending the commits to this PR so that we can get on with merging this? It can stimulate the necessary discussions about using saltcheck for other formulas as well.

@myii
Copy link
Member

myii commented Oct 18, 2019

@mchugh19 OK, I've pushed a few more commits here, after a discussion with @javierbertoli about some concerns. It follows on from the same points made by @daks previously, starting in saltstack-formulas/template-formula#88. @aboe76 You may find this interesting, also.

One of the main concerns is that saltcheck will end up being blind-sided by sharing the same codebase as the Salt modules, states and formulas. One issue is the shared use of map.jinja -- if there's a problem there, saltcheck will fail to catch the problem since it is broken in exactly the same way. So we're going to approach this more like we do with InSpec -- separating the execution between the code and the tests as much as possible. So no shared map.jinja; in fact, no map.jinja at all.

One thing I've been able to do (and appreciate) is the near 1:1 relationship between the code and the tests. You can literally work through the .sls in blocks from top to bottom, writing tests for each section as you go along. It feels like you could achieve maximum test coverage with this method. To help explain that, I'm going to diff each section of the .sls and .tst, to appreciate how similar they are. It would have been easier to do this side-by-side but GitHub isn't the easiest place to do this. So I'm going to allow myself a little leeway, so that lines that are effectively the same don't drown things out. The - side is the .sls and the + side is the .tst.

[1] Getting the data

-{%- from tplroot ~ "/map.jinja" import cron with context %}
+{%- set cron = salt['pillar.get']('cron', {}) %}
  • Only using pillar.get to pull in the test pillar at test/salt/pillar/cron.sls.
  • Since this is a Salt module, I figured that this is the middle ground.
  • I've also tested with literal values and it works fine but it's too much effort to maintain, in my opinion, with nothing being gained:
{%- set cron = {
        'enabled': true,
        'tasks': {
            'task1': {
                'type': 'present',
                'name': 'echo test > /tmp/test',
                'user': 'root',
                'minute': 0,
                'hour': 0,
                'daymonth': 7,
                'month': 1,
                'dayweek': 6,
                'comment': 'comment1',
                'commented': false,
            },
            'task2': {
                'type': 'absent',
                'name': 'echo task2 > /tmp/test2',
                'user': 'root',
                'minute': 'random',
                'hour': 1,
            },
            'task3': {
                'type': 'present',
                'name': 'echo task3 > /tmp/test3',
                'user': 'root',
                'special': '@hourly',
                'comment': 'comment3',
            },
            'task4': {
                'type': 'present',
                'name': 'echo task4 > /tmp/test4',
                'user': 'root',
                'minute': '*/5',
                'hour': '*',
                'comment': 'comment4',
            },
            'task5': {
                'type': 'present',
                'name': 'echo task5 > /tmp/test5',
                'user': 'root',
                'minute': 'random',
                'hour': 1,
                'commented': true,
            },
        },
    } %}

[2] Loop/variables

 {%- for task, task_options in cron.get('tasks', {}).items() %}
 {%-   set cron_type = task_options.type|d('present') %}
  • Identical on both sides.

[3] Cron entry present/absent

-cron.{{ task }}:
-  cron.{{ cron_type }}:
-    - name: {{ task_options.name }}
-    - user: {{ task_options.user|d('root') }}
-    - identifier: '{{ task }}'
+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 %}
  • Identical expressions used on both sides.

[4] Continue the rest of .sls/.tst for present only

 {%- if cron_type == 'present' %}
  • Identical on both sides.

[5] Test for commented

-    - commented: {{ task_options.commented|d(False) }}
+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
  • Using the same expression on both sides.

[6] Inner loop and conditional

+{#-   Note: `special` is `spec` in the module #}
- {%-   for section in ['minute', 'hour', 'daymonth', 'month', 'dayweek', 'comment', 'special'] %}
+ {%-   for section in ['minute', 'hour', 'daymonth', 'month', 'dayweek', 'comment', 'spec'] %}
 {%-     if section in task_options %}
  • Essentially identical again on both sides.

[7] Testing every cron setting

-    - {{ section }}: '{{ task_options[section] }}'
+{%-       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 }}'
  • Made slightly more complicated by the way random works but even then, an easy translation.
  • This little block already provides almost 20 tests, effectively every item from the pillar data is tested.

[8] Closing all of the loops and conditionals

    {%-     endif %}
    {%-   endfor %}
    {%- endif %}

{%- endfor %}
  • Identical on both sides.

Compare the two files side-by-side in an editor, to appreciate the similarities I attempted to highlight above.

In terms of the results:

             ----------
             TEST RESULTS:
          ----------
          Execution Time:
              3.7203
          Failed:
              0
          Missing Tests:
              0
          Passed:
              25
          Skipped:
              0
  • Scroll up from there to see details of all of the tests that were run.

@mchugh19
Copy link
Author

Agreed @myii, I also appreciate how being able to leverage salt modules for testing gives deep introspection for validation and test coverage (I originally patched saltcheck to suit our needs when deploying large hadoop clusters in multi cloud environments and needing to ensure that data stores, xml hadoop configs, versioned jar deployments, databases, and seeded data were all in the expected state). As you say, it's also powerful in by leveraging jinja and the salt renderer, you keep a very similar syntax, and can access map.jinja or pillars as desired.

I think there are a few different ways you could treat saltcheck testing. For formula CI processes, you could test

  1. The result of the map.jinja data inheritance process itself
  2. That pillar data results in expected output on a machine
  3. That duplicated or independent known data exists on the machine in the expected state

The #3 option is how I've witnessed most inspect tests, but why not do both? If you want to be paranoid and double check the map.jinja process or pillars, you could have the #1 or #2 tests, and a static dictionary of validation data feed into your CI tests.

Additionally, these are formulas intended for use by the community. As such, including saltcheck tests which can be run by the end-users (like #1 or #2 above) give further confidence in their robustness and that the pillar docs all actually functioned. I think that even if you didn't use saltcheck as the primary CI validation tool, that it still makes sense to ship saltcheck tests so that functionality and validation can be testing can be leveraged by users.

I do understand the reluctance to use a tool to test itself, but you also want to draw a line around what is being tested. Should pillar.get be broken, it is not the job of the saltstack-formulas/foo CI process to catch this, but instead the unit tests around the pillar module itself. The saltstack-formulas tests should be able to rely on a functioning salt system and validate the logic of the formulas themselves and focus on excellent coverage of the data and features exposed.

@myii
Copy link
Member

myii commented Oct 18, 2019

And another, required (final) commit. It also contains a couple of examples of how saltcheck and InSpec share similarities.

Package:

        *InSpec*        |                   *Saltcheck*
------------------------+-------------------------------------------------
package_name =          | {%- set package_name = 'cronie' %}
  case os[:family]      |
  when 'debian'         | {%- if grains.os_family in ['Debian'] %}
    'cron'              | {%-   set package_name = 'cron' %}
  else                  |
    'cronie'            |
  end                   | {%- endif %}

Service:

        *InSpec*        |                   *Saltcheck*
------------------------+-------------------------------------------------
service_name =          | {%- set service_name = 'crond' %}
  case os[:family]      |
  when 'debian', 'suse' | {%- if grains.os_family in ['Debian', 'Suse'] %}
    'cron'              | {%-   set service_name = 'cron' %}
  when 'linux'          |
    case os[:name]      |
    when 'arch'         | {%- elif grains.os_family in ['Arch'] %}
      'cronie'          | {%-   set service_name = 'cronie' %}
    else                |
      'crond'           |
    end                 |
  else                  |
    'crond'             |
  end                   | {%- endif %}
  • Arguably, saltcheck is simpler to work with in this example.

@myii
Copy link
Member

myii commented Oct 19, 2019

@mchugh19 Referring back to an earlier comment here: #4 (comment).

... it looks like it stops searching for paths when it finds the first one, that's why the rest of the tests aren't found.

Due the 1:1 relationship between state file and test file, it would be preferable to have the tests within each sub-directory instead. Had a look at the code and got to the bottom of this.

Note: All of the below was when testing with:

$ ... saltcheck.run_state_tests cron check_all=True

Looking at paths being evaluated with no saltcheck-tests directories present

state_name: cron.package.install
looking in %s to cache tests salt://cron/package/install/saltcheck-tests
looking in %s to cache tests salt://cron/package/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.service.running
looking in %s to cache tests salt://cron/service/running/saltcheck-tests
looking in %s to cache tests salt://cron/service/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests

It's checking cron.config.file numerous times unnecessarily. Had to move processed_states.append(state_name) into the if higher up:

                if state_name in processed_states:
                    copy_states = False
                else:
                    processed_states.append(state_name)

Resulting in:

state_name: cron.package.install
looking in %s to cache tests salt://cron/package/install/saltcheck-tests
looking in %s to cache tests salt://cron/package/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.service.running
looking in %s to cache tests salt://cron/service/running/saltcheck-tests
looking in %s to cache tests salt://cron/service/saltcheck-tests

Gathering all of the tests (not just the first directory found)

Enabled the tests directory under cron.package.install only, resulting in:

state_name: cron.package.install
looking in %s to cache tests salt://cron/package/install/saltcheck-tests
looking in %s to cache tests salt://cron/package/saltcheck-tests
BREAK
  • It stops looking beyond that point.

Resolved by disabling the break statements:

state_name: cron.package.install
looking in %s to cache tests salt://cron/package/install/saltcheck-tests
looking in %s to cache tests salt://cron/package/saltcheck-tests  
BREAK (disabled)
Adding .tst file: %s /tmp/kitchen/var/cache/salt/minion/files/base/cron/package/saltcheck-tests/install.tst
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
looking in %s to cache tests salt://cron/saltcheck-tests
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.service.running
looking in %s to cache tests salt://cron/service/running/saltcheck-tests
looking in %s to cache tests salt://cron/service/saltcheck-tests
  • So now it continues to scan the rest of the directories for tests, as it's supposed to.

Enabled the tests directories under cron.config.file and cron.service.running and now working as required:

state_name: cron.package.install
looking in %s to cache tests salt://cron/package/install/saltcheck-tests
looking in %s to cache tests salt://cron/package/saltcheck-tests
BREAK (disabled)
Adding .tst file: %s /tmp/kitchen/var/cache/salt/minion/files/base/cron/package/saltcheck-tests/install.tst
state_name: cron.config.file
looking in %s to cache tests salt://cron/config/file/saltcheck-tests
looking in %s to cache tests salt://cron/config/saltcheck-tests
BREAK (disabled)
Adding .tst file: %s /tmp/kitchen/var/cache/salt/minion/files/base/cron/config/saltcheck-tests/file.tst
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.config.file
state_name: cron.service.running
looking in %s to cache tests salt://cron/service/running/saltcheck-tests
looking in %s to cache tests salt://cron/service/saltcheck-tests  
BREAK (disabled)

...

      ----------
      TEST RESULTS:
          ----------
          Execution Time:
              3.5308
          Failed:
              0
          Missing Tests:
              0
          Passed:
              25
          Skipped:
              0

Adapted in this formula

I've added another commit here to use this improved structure. That includes renaming the .tst files to match the name of the relevant .sls files, to clearly show the 1:1 relationship. While not critical in this small formula, this implementation is an exemplar for other formula conversions, where this would be much more significant. In fact, I'd prefer if we avoided the base directory of salt://<formula>/package/saltcheck-tests entirely. So I've gone back to using the version of saltcheck.py from neon, with these minor adjustments made.

myii added a commit to mchugh19/cron-formula that referenced this pull request Oct 19, 2019
@myii
Copy link
Member

myii commented Oct 19, 2019

For clarity, .tst files have been renamed and relocated according to their relevant (1:1) .sls files:

.sls file .tst file
.../cron/package/install.sls .../cron/package/saltcheck-tests/install.tst
.../cron/config/file.sls .../cron/config/saltcheck-tests/file.tst
.../cron/service/running.sls .../cron/service/saltcheck-tests/running.tst
  • This structure will be far more appropriate if used for formulas with numerous state files under each directory.
  • It also gives a clearer indication of test coverage; at a glance, it will be easier to determine which state files have tests written for them.

@mchugh19
Copy link
Author

Good updates @myii! I'm traveling for the next week, but I'll incorporate your solution into the saltcheck patches when I'm back home. Thanks!

@myii
Copy link
Member

myii commented Oct 22, 2019

After suggestions from @daks and @aboe76, rearranged all of the test files under a single root-level saltcheck-tests directory, as follows:

.sls file .tst file
.../cron/package/install.sls .../cron/saltcheck-tests/package/install.tst
.../cron/config/file.sls .../cron/saltcheck-tests/config/file.tst
.../cron/service/running.sls .../cron/saltcheck-tests/service/running.tst

... So I've gone back to using the version of saltcheck.py from neon, with these minor adjustments made.

With this change, I've readjusted again to base the saltcheck.py being used on #4 (comment).

@aboe76
Copy link
Member

aboe76 commented Oct 22, 2019

@myii wow, that's quick.

@myii myii merged commit 7e6742b into saltstack-formulas:master Oct 23, 2019
@myii
Copy link
Member

myii commented Oct 23, 2019

Our first saltcheck-enabled formula is now active! Thanks for getting this started, @mchugh19.

saltstack-formulas-travis pushed a commit that referenced this pull request Oct 23, 2019
## [0.2.4](v0.2.3...v0.2.4) (2019-10-23)

### Bug Fixes

* **saltcheck:** fix broken import and standardise across test files ([](7911b71))
* **saltcheck:** fix invalid `service` test ([](677c956))
* **saltcheck:** remove trailing spaces ([](aada0ae))
* **saltcheck:** replace `map.jinja` references with InSpec conditionals ([](7e9e619))
* **saltcheck:** update for `cron` instead of `cron_settings` ([](26cfa4f))

### Code Refactoring

* **config:** minimise and standardise between `.sls` & `.tst` ([](18585bd))
* **config:** remove duplication in using a loop ([](652ebff))
* **jinja:** used shortened form of `|default` filter ([](a0f891e))
* **saltcheck:** relocate `.tst` files according to 1:1 `.sls` files ([](ee65236)), closes [/github.com//pull/4#issuecomment-544140377](https://github.com//github.com/saltstack-formulas/cron-formula/pull/4/issues/issuecomment-544140377)
* **saltcheck:** use `package.tst` instead of `install.tst` ([](d2c9544))
* **saltcheck:** use root-level `saltcheck-tests` directory ([](6e54c3f))

### Continuous Integration

* **travis:** obtain `saltcheck.py` and run the tests (only on `develop`) ([](8ae46e5))
* **travis:** run `salt-lint` for `.tst` files as well ([](baab964))
* **travis:** standardise `saltcheck` comments ([](e23276b))
* **travis:** update `salt-lint` config for `v0.0.10` [skip ci] ([](b701d79))

### Styles

* **config.tst:** rearrange Jinja statements for clarity ([](8abec54))
* **saltcheck:** merge `absent` & `present` into one `if` block ([](33f344c))
* **saltcheck:** use consistent order of assertions ([](88229f0))

### Tests

* **pillar:** add test for `commented` and clarify each test ([](3d0dcb2))
* **pillar:** ensure `special` is being tested as well ([](951a959))
* **saltcheck:** add first tests ([](9847aff))
* **saltcheck:** add support for `random` values ([](007970f))
* **saltcheck:** add test for `service.available` ([](226eb88))
* **saltcheck:** add test for `service.running` ([](5cdc50f))
* **saltcheck:** avoid `map.jinja`, use the test pillar instead ([](cce5e67))
* **saltcheck:** fix `config` tests ([](9225b18))
* **saltcheck:** remove duplication in `config.tst` using a loop ([](72281c7))
* **saltcheck:** test for `commented` and not `commented` ([](5070611))
* **saltcheck:** test for `special` in `config.tst` as well ([](6f2b323))
* **saltcheck:** use local `map.jinja` to workaround missing `tpldata` ([](8845b3c))
@saltstack-formulas-travis

🎉 This PR is included in version 0.2.4 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants