# 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
