bundle common test_meta
{
  vars:
    "description"
      string => "Test that multiple packages not installed gets installed";

    "story_id" string => "5513";
    "covers" string => "operational_repaired";
}

#######################################################
body common control
{
  inputs => {
    "../../../dcs.sub.cf",
    "../../../../../$(sys.local_libdir)/stdlib.cf",
    "../../../../../$(sys.local_libdir)/packages.cf",
    "../../packages-info.cf.sub",
    "../../meta_skip.cf.sub",
  };
  bundlesequence => { default("$(this.promise_filename)") };
  version => "1.0";
  cache_system_functions => "no";
}

#######################################################
bundle agent init
{
  methods:
    "clear_packages" usebundle => clear_packages("dummy");
}

#######################################################
bundle agent test
{
  vars:
    "package_name" slist => { "$(p.name[3])", "$(p.name[1])", "$(p.name[2])" };

  packages:
    debian::
      "$(package_name)"
        package_policy => "add",
        classes => test_set_class(
          "pass_$(package_name)", "fail_$(package_name)"
        );

    redhat::
      "$(package_name)"
        package_policy => "add",
        classes => test_set_class(
          "pass_$(package_name)", "fail_$(package_name)"
        );

    suse|sles::
      "$(package_name)"
        package_policy => "add",
        classes => test_set_class(
          "pass_$(package_name)", "fail_$(package_name)"
        );
}

body classes test_set_class(ok_class, notok_class)
{
  promise_kept => { "$(ok_class)" };
  promise_repaired => { "$(ok_class)" };
  repair_failed => { "$(notok_class)" };
}

#######################################################
bundle agent check
{
  classes:
    debian::
      "has_pkg_$(test.package_name)"
        expression => returnszero(
          "dpkg -l | egrep ' $(test.package_name)(:$(p.arch))? '", "useshell"
        );

    redhat|suse|sles::
      "has_pkg_$(test.package_name)"
        expression => returnszero(
          "/bin/rpm -qa | grep -qw $(test.package_name)", "useshell"
        );

    any::
      "has_file_test_package_charlie"
        expression => fileexists("$(p.file[3][$(p.latest_version)])");

      "has_file_test_package_alpha"
        expression => fileexists("$(p.file[1][$(p.latest_version)])");

      "has_file_test_package_beta"
        expression => fileexists("$(p.file[2][$(p.latest_version)])");

      # Would be nice to test the pass_* and fail_* classes here, but CFEngine
      # doesn't set the classes properly when installing multiple new packages.
      "charlie_ok"
        and => {
          #"pass_test_package_charlie", "!fail_test_package_charlie",
          "has_pkg_test_package_charlie",
          "has_file_test_package_charlie",
        };

      "alpha_ok"
        and => {
          #"pass_test_package_alpha", "!fail_test_package_alpha",
          "has_pkg_test_package_alpha",
          "has_file_test_package_alpha",
        };

      "beta_ok"
        and => {
          #"pass_test_package_beta", "!fail_test_package_beta",
          "has_pkg_test_package_beta",
          "has_file_test_package_beta",
        };

      "ok" and => { "charlie_ok", "alpha_ok", "beta_ok" };

  reports:
    ok::
      "$(this.promise_filename) Pass";

    !ok::
      "$(this.promise_filename) FAIL";
}
