---
- name: "Ensure that the role runs with parameters for
  basics input and files output"
  hosts: all
  vars:
    __test_default_files_conf: /etc/rsyslog.d/30-output-files-default_files.conf
    __test_files_conf0: /etc/rsyslog.d/30-output-files-files_output0.conf
    __test_files_conf1: /etc/rsyslog.d/30-output-files-files_output1.conf
    __test_files_conf2: /etc/rsyslog.d/30-output-files-files_output2.conf
    __test_files_conf3: /etc/rsyslog.d/30-output-files-files_output3.conf
    __test_files_conf4: /etc/rsyslog.d/30-output-files-files_output4.conf
    __test_local_module: /etc/rsyslog.d/10-local-modules.conf
    __test_forwards_conf: >-
      /etc/rsyslog.d/30-output-forwards-forwards_severity_and_facility.conf
    __default_system_log: /var/log/messages
    __prop_based_log0: /var/log/property_based_filter_in.log
    __prop_based_log1: /var/log/property_based_filter_out.log
    __logging_system_log_dir: '/var/log/rsyslog'

  tasks:
    # TEST CASE 0
    - name: "TEST CASE 0; Test the simplest configuration,
      basics input and implicit files output with logging_mark enabled"
      vars:
        logging_manage_firewall: true
        logging_manage_selinux: true
        logging_mark: true
        logging_mark_interval: "7200"
        logging_inputs:
          - name: basic_input
            type: basics
      include_role:
        name: linux-system-roles.logging
        public: true

    # notify Restart rsyslogd is executed at the end of this test task.
    # thus we have to force to invoke handlers
    - name: "Force all notified handlers to run at this point,
      not waiting for normal sync points"
      meta: flush_handlers

    - name: Ensure config file size and counts
      vars:
        __conf_count: 5
        __conf_size: less
        __conf_files:
          - "{{ __test_default_files_conf }}"
        __check_systemctl_status: true
      include_tasks: tasks/check_daemon_config_files.yml

    - name: Grep output to messages line
      command: >-
        /bin/grep
        '*.info;mail.none;authpriv.none;cron.none.*{{ __default_system_log }}'
        {{ __test_default_files_conf }}
      changed_when: false

    - name: Ensure logger message is logged in a file
      vars:
        __logging_index: 0
        __logging_file: "{{ __default_system_log }}"
      include_tasks: tasks/test_logger.yml

    - name: Check ports managed by firewall and selinux
      include_tasks: tasks/check_firewall_selinux.yml

    - name: Ensure immark interval value is in quotes
      shell: |-
        set -euo pipefail
        grep "module.*immark.*interval" "{{ __test_local_module }}" | \
        sed -e "s/module.*interval=\(.*\))/\1/"
      register: __result
      changed_when: false
      failed_when: __result.stdout != "\"7200\""

    - name: END TEST CASE 0; Clean up the deployed config
      vars:
        logging_purge_confs: true
        logging_manage_firewall: false
        logging_manage_selinux: false
        logging_inputs: []
        logging_outputs: []
        logging_flows: []
      include_role:
        name: linux-system-roles.logging
        public: true

    - name: Check ports managed by firewall and selinux
      include_tasks: tasks/check_firewall_selinux.yml

    # notify Restart rsyslogd is executed at the end of this test task.
    # thus we have to force to invoke handlers
    - name: "Force all notified handlers to run at this point,
      not waiting for normal sync points"
      meta: flush_handlers

    # TEST CASE 1
    - name: "TEST CASE 1; logging_system_log_dir -
      test switching the local log output file location"
      vars:
        logging_manage_firewall: true
        logging_manage_selinux: false
        logging_system_log_dir: "{{ __logging_system_log_dir }}"
        logging_outputs:
          - name: files_output0
            type: files
        logging_inputs:
          - name: basic_input
            type: basics
        logging_flows:
          - name: flows0
            inputs: [basic_input]
            outputs: [files_output0]
      include_role:
        name: linux-system-roles.logging
        public: true

    # notify Restart rsyslogd is executed at the end of this test task.
    # thus we have to force to invoke handlers
    - name: "Force all notified handlers to run at this point,
      not waiting for normal sync points"
      meta: flush_handlers

    - name: Ensure config file size and counts
      vars:
        __conf_count: 5
        __conf_size: less
        __conf_files:
          - "{{ __test_files_conf0 }}"
        __check_systemctl_status: true
      include_tasks: tasks/check_daemon_config_files.yml

    - name: Ensure logger message is logged in a file
      vars:
        __logging_index: 2
        __logging_file: "{{ __logging_system_log_dir }}/messages"
      include_tasks: tasks/test_logger.yml

    # yamllint disable rule:line-length
    - name: "Check the files output config that the messages path is
      {{ __logging_system_log_dir }}"
      command: >-
        /bin/grep
        '\*.info;mail.none;authpriv.none;cron.none.*{{ __logging_system_log_dir }}/messages'
        {{ __test_files_conf0 }}
      register: __result
      until: __result is success
      retries: 5
      delay: 1
      changed_when: false
    # yamllint enable rule:line-length

    - name: Check ports managed by firewall and selinux
      include_tasks: tasks/check_firewall_selinux.yml

    - name: END TEST CASE 1; Clean up the deployed config
      vars:
        logging_purge_confs: true
        logging_manage_firewall: false
        logging_manage_selinux: false
        logging_inputs: []
        logging_outputs: []
        logging_flows: []
      include_role:
        name: linux-system-roles.logging
        public: true

    - name: Check ports managed by firewall and selinux
      include_tasks: tasks/check_firewall_selinux.yml

    # notify Restart rsyslogd is executed at the end of this test task.
    # thus we have to force to invoke handlers
    - name: "Force all notified handlers to run at this point,
      not waiting for normal sync points"
      meta: flush_handlers

    # TEST CASE 2
    - name: Test case 2
      vars:
        __expected_error: >
          Error: ['bogus_basic_input'] includes undefined logging_inputs item.
        __expected_error2: >
          Error: [u'bogus_basic_input'] includes undefined logging_inputs item.
      block:
        - name: "TEST CASE 2; Test the configuration, which flow
          contains a undefined input bogus_basic_input"
          vars:
            logging_outputs:
              - name: files_output0
                type: files
                facility: authpriv,auth
                path: /var/log/secure
              - name: files_output1
                type: files
                severity: info
                exclude:
                  - authpriv.none
                  - auth.none
                  - cron.none
                  - mail.none
                path: "{{ __default_system_log }}"
              - name: files_output2
                type: files
                severity: emerg
                path: :omusrmsg:*
              - name: files_output3
                type: files
                facility: local7
                path: /var/log/boot.log
            logging_inputs:
              - name: basic_input
                type: basics
            logging_flows:
              - name: flow_0
                inputs: [bogus_basic_input]
                outputs:
                  - files_output0
                  - files_output1
                  - files_output2
                  - files_output3
          include_role:
            name: linux-system-roles.logging

        - name: Unreachable task
          fail:
            msg: UNREACH
      rescue:
        - name: Expected error
          debug:
            msg: "{{ ansible_failed_result }}"
        - name: Ensure the expected error message is issued
          assert:
            that: ansible_failed_result.results.0.msg == __expected_error or
                  ansible_failed_result.results.0.msg == __expected_error2

    - name: END TEST CASE 2; Clean up the deployed config
      vars:
        logging_purge_confs: true
        logging_inputs: []
        logging_outputs: []
        logging_flows: []
      include_role:
        name: linux-system-roles.logging

    # notify Restart rsyslogd is executed at the end of this test task.
    # thus we have to force to invoke handlers
    - name: "Force all notified handlers to run at this point,
      not waiting for normal sync points"
      meta: flush_handlers

    # TEST CASE 3
    - name: "TEST CASE 3; Ensure that the role runs with parameters
      from imjournal input to two omfile and two omfwd outputs"
      vars:
        logging_manage_firewall: false
        logging_manage_selinux: true
        logging_purge_confs: true
        logging_outputs:
          - name: files_output0
            type: files
            severity: info
            exclude:
              - authpriv.none
              - auth.none
              - cron.none
              - mail.none
            path: "{{ __default_system_log }}"
          - name: files_output1
            type: files
            facility: authpriv,auth
            path: /var/log/secure
          - name: forwards_severity_and_facility
            type: forwards
            facility: local1
            severity: info
            target: host.domain
            tcp_port: 1514
          - name: forwards_facility_only
            type: forwards
            facility: local2
            target: host.domain
            tcp_port: 2514
        logging_inputs:
          - name: basic_input0
            type: basics
        logging_flows:
          - name: flow_0
            inputs: [basic_input0]
            outputs:
              - files_output0
              - files_output1
              - forwards_severity_and_facility
              - forwards_facility_only
      include_role:
        name: linux-system-roles.logging
        public: true

    # notify Restart rsyslogd is executed at the end of this test task.
    # thus we have to force to invoke handlers
    - name: "Force all notified handlers to run at this point,
      not waiting for normal sync points"
      meta: flush_handlers

    - name: Ensure config file size and counts
      vars:
        __conf_count: 8
        __conf_size: less
        __conf_files:
          - "{{ __test_files_conf0 }}"
          - "{{ __test_files_conf1 }}"
          - "{{ __test_forwards_conf }}"
        __check_systemctl_status: true
      include_tasks: tasks/check_daemon_config_files.yml

    # yamllint disable rule:line-length
    - name: Check the filter
      command: >-
        /bin/grep
        '\*.info;authpriv.none;auth.none;cron.none;mail.none.*{{ __default_system_log }}'
        {{ __test_files_conf0 }}
      changed_when: false
    # yamllint enable rule:line-length

    - name: Ensure logger message is logged in a file
      vars:
        __logging_index: 3
        __logging_file: "{{ __default_system_log }}"
      include_tasks: tasks/test_logger.yml

    - name: Generate a file to check severity_and_facility
      copy:
        dest: /tmp/__testfile__
        content: |
          #
          # Ansible managed
          #
          ruleset(name="forwards_severity_and_facility") {
              local1.info action(name="forwards_severity_and_facility"
                  type="omfwd"
                  Target="host.domain"
                  Port="1514"
                  Protocol="tcp"
                  Template="RSYSLOG_ForwardFormat"
              )
          }
        mode: '0600'

    - name: Check severity_and_facility
      command: diff -B /tmp/__testfile__ '{{ __test_forwards_conf }}'
      changed_when: false

    - name: Check ports managed by firewall and selinux
      include_tasks: tasks/check_firewall_selinux.yml

    - name: END TEST CASE 3; Clean up the deployed config
      vars:
        logging_purge_confs: true
        logging_manage_firewall: false
        logging_manage_selinux: false
        logging_inputs: []
        logging_outputs: []
        logging_flows: []
      include_role:
        name: linux-system-roles.logging
        public: true

    - name: Check ports managed by firewall and selinux
      include_tasks: tasks/check_firewall_selinux.yml

    - name: Cleaning up __testfile__
      file:
        path: /tmp/__testfile__
        state: absent
