# Test that monitoring file status of an updated file gives right promises
# status.

body common control
{
      inputs => { "../../default.sub.cf", "check_file_changes_log.cf.sub" };
      bundlesequence  => { default("$(this.promise_filename)") };
}

bundle agent init
{
  files:
      # Not in database.
      "$(G.testfile).update.new"
        create => "true";
      # Should be in database.
      "$(G.testfile).update.same"
        create => "true",
        changes => test_changes_update;
      "$(G.testfile).update.updated"
        create => "true",
        changes => test_changes_update;

      # Not in database.
      "$(G.testfile).noupdate.new"
        create => "true";
      # Should be in database.
      "$(G.testfile).noupdate.same"
        create => "true",
        changes => test_changes_nohasheupdate_report_changes_all;
      "$(G.testfile).noupdate.updated"
        create => "true",
        changes => test_changes_nohasheupdate_report_changes_all;
}

bundle agent test
{
   meta:
      "test_soft_fail" string => "windows",
        meta => { "ENT-10254" };

  files:
      "$(G.testfile).update.updated"
        edit_line => insert_text;
      "$(G.testfile).noupdate.updated"
        edit_line => insert_text;

  methods:
      # Update each file twice. We cannot reuse the bundles because CFEngine
      # will skip bundles it has done before.
      "test_update_new" usebundle => test_update_new;
      "test_update_same" usebundle => test_update_same;
      "test_update_updated" usebundle => test_update_updated;
      "test_update_new_again" usebundle => test_update_new_again;
      "test_update_same_again" usebundle => test_update_same_again;
      "test_update_updated_again" usebundle => test_update_updated_again;

      "test_noupdate_new" usebundle => test_noupdate_new;
      "test_noupdate_same" usebundle => test_noupdate_same;
      "test_noupdate_updated" usebundle => test_noupdate_updated;
      "test_noupdate_new_again" usebundle => test_noupdate_new_again;
      "test_noupdate_same_again" usebundle => test_noupdate_same_again;
      "test_noupdate_updated_again" usebundle => test_noupdate_updated_again;
}

bundle edit_line insert_text
{
  insert_lines:
      "Text";
}

bundle agent test_update_new
{
  files:
      "$(G.testfile).update.new"
        changes => test_changes_update,
        classes => kept_repaired_notkept("test_update_new_kept", "test_update_new_repaired", "test_update_new_notkept");
}

bundle agent test_update_same
{
  files:
      "$(G.testfile).update.same"
        changes => test_changes_update,
        classes => kept_repaired_notkept("test_update_same_kept", "test_update_same_repaired", "test_update_same_notkept");
}

bundle agent test_update_updated
{
  files:
      "$(G.testfile).update.updated"
        changes => test_changes_update,
        classes => kept_repaired_notkept("test_update_updated_kept", "test_update_updated_repaired", "test_update_updated_notkept");
}

bundle agent test_update_new_again
{
  files:
      "$(G.testfile).update.new"
        changes => test_changes_update,
        classes => kept_repaired_notkept("test_update_new_kept", "test_update_new_repaired", "test_update_new_notkept");
}

bundle agent test_update_same_again
{
  files:
      "$(G.testfile).update.same"
        changes => test_changes_update,
        classes => kept_repaired_notkept("test_update_same_kept", "test_update_same_repaired", "test_update_same_notkept");
}

bundle agent test_update_updated_again
{
  files:
      "$(G.testfile).update.updated"
        changes => test_changes_update,
        classes => kept_repaired_notkept("test_update_updated_kept", "test_update_updated_repaired", "test_update_updated_notkept");
}

bundle agent test_noupdate_new
{
  files:
      "$(G.testfile).noupdate.new"
        changes => test_changes_nohasheupdate_report_changes_all,
        classes => kept_repaired_notkept("test_noupdate_new_kept", "test_noupdate_new_repaired", "test_noupdate_new_notkept");
}

bundle agent test_noupdate_same
{
  files:
      "$(G.testfile).noupdate.same"
        changes => test_changes_nohasheupdate_report_changes_all,
        classes => kept_repaired_notkept("test_noupdate_same_kept", "test_noupdate_same_repaired", "test_noupdate_same_notkept");
}

bundle agent test_noupdate_updated
{
  files:
      "$(G.testfile).noupdate.updated"
        changes => test_changes_nohasheupdate_report_changes_all,
        classes => kept_repaired_notkept("test_noupdate_updated_kept", "test_noupdate_updated_repaired", "test_noupdate_updated_notkept");
}

bundle agent test_noupdate_new_again
{
  files:
      "$(G.testfile).noupdate.new"
        changes => test_changes_nohasheupdate_report_changes_all,
        classes => kept_repaired_notkept("test_noupdate_new_kept", "test_noupdate_new_repaired", "test_noupdate_new_notkept");
}

bundle agent test_noupdate_same_again
{
  files:
      "$(G.testfile).noupdate.same"
        changes => test_changes_nohasheupdate_report_changes_all,
        classes => kept_repaired_notkept("test_noupdate_same_kept", "test_noupdate_same_repaired", "test_noupdate_same_notkept");
}

bundle agent test_noupdate_updated_again
{
  files:
      "$(G.testfile).noupdate.updated"
        changes => test_changes_nohasheupdate_report_changes_all,
        classes => kept_repaired_notkept("test_noupdate_updated_kept", "test_noupdate_updated_repaired", "test_noupdate_updated_notkept");
}

body changes test_changes_update
{
      hash           => "sha256";
      report_changes => "all";
      update_hashes  => "yes";
}

body changes test_changes_nohasheupdate_report_changes_all
{
      hash           => "sha256";
      report_changes => "all";
      update_hashes  => "no";
}

body classes kept_repaired_notkept(kept, repaired, notkept)
{
      promise_kept => { "$(kept)" };
      promise_repaired => { "$(repaired)" };
      repair_failed    => { "$(notkept)" };
      repair_denied    => { "$(notkept)" };
      repair_timeout   => { "$(notkept)" };
}

bundle agent check
{
  vars:
      "classes_set" slist => classesmatching("test_.*");

  methods:
      # Seems like CFEngine does two passes over files where we don't update
      # hash, so the last four entries should really be two entries.
      # If the number of "Content changed" lines is wrong, this is the first
      # place to look.
      "any" usebundle => file_make("$(G.testfile).file_changes_log", "TEST.cfengine.update.updated,C,Content changed
TEST.cfengine.noupdate.updated,C,Content changed
TEST.cfengine.noupdate.updated,C,Content changed
TEST.cfengine.noupdate.updated,C,Content changed
TEST.cfengine.noupdate.updated,C,Content changed");

      "any" usebundle => check_file_changes_log("$(G.testfile).file_changes_log", "test_changes_log_ok",
                                                "test_changes_log_fail", "");

  classes:
      "ok" and => {
                    "checksum_alerts",
                    "test_update_new_repaired",
                    "!test_update_new_notkept",
                    "!test_update_same_repaired",
                    "test_update_same_kept",
                    "!test_update_same_notkept",
                    "test_update_updated_repaired",
                    "!test_update_updated_notkept",
                    "test_noupdate_new_repaired",
                    "!test_noupdate_new_notkept",
                    "!test_noupdate_same_repaired",
                    "test_noupdate_same_kept",
                    "!test_noupdate_same_notkept",
                    "test_noupdate_updated_repaired", # because changes are recorded in the changes log
                    "test_noupdate_updated_notkept",  # because hashes are not updated
                    "test_changes_log_ok",
                    "!test_changes_log_fail",
      };

  reports:
    DEBUG::
      "Set classes: $(classes_set)";
    !checksum_alerts.DEBUG::
      "The checksum_alerts class was NOT set as expected.";
    checksum_alerts.EXTRA::
      "The checksum_alerts class was set as expected.";
    ok::
      "$(this.promise_filename) Pass";
    !ok::
      "$(this.promise_filename) FAIL";
}
### PROJECT_ID: core
### CATEGORY_ID: 27
