Repository: dell/dellemc-openmanage-ansible-modules
Pull request #843: Adding support for lifecycle controller job status info for 17G
Author: login: trisha-dell
Labels: name: validation/completed
description: Validation is completed
Created: 2025-04-04T05:56:05Z | Merged: 2025-04-23T17:04:48Z

# Description
Adding support for lifecycle controller job status info for 17G

# ISSUE TYPE
- Feature Pull Request

# Checklist:

- [x] I have performed a self-review of my own code to ensure there are no formatting, vetting, linting, or security issues
- [x] I have verified that new and existing unit tests pass locally with my changes
- [x] I have not allowed coverage numbers to degenerate
- [x] I have maintained at least 90% code coverage
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] I have maintained backward compatibility


Diff:
diff --git a/plugins/module_utils/idrac_utils/info/lifecycle_controller_job_status.py b/plugins/module_utils/idrac_utils/info/lifecycle_controller_job_status.py
new file mode 100644
index 000000000..ba545a385
--- /dev/null
+++ b/plugins/module_utils/idrac_utils/info/lifecycle_controller_job_status.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+
+# Dell OpenManage Ansible Modules
+# Version 9.12.0
+# Copyright (C) 2025 Dell Inc. or its subsidiaries. All Rights Reserved.
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+#    * Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+
+#    * Redistributions in binary form must reproduce the above copyright notice,
+#      this list of conditions and the following disclaimer in the documentation
+#      and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10 = "/redfish/v1/Managers/iDRAC.Embedded.1"
+NA = "Not Available"
+odata = "@odata.id"
+
+
+class IDRACLifecycleControllerJobStatusInfo(object):
+    def __init__(self, idrac):
+        self.idrac = idrac
+
+    def transform_job_status_data(self, info_data):
+        job_success_list = ['Completed', 'Success']
+        job_failed_list = ['Failed', 'Errors']
+        job_state = str(info_data.get("JobState", NA))
+        if job_state in job_success_list:
+            job_status = "Success"
+        elif job_state in job_failed_list:
+            job_status = "Failed"
+        elif 'Message' in info_data and str(info_data.get("Message")) and \
+                'completed' in str(info_data.get("Message")) and \
+                'errors' not in str(info_data.get("Message")):
+            job_status = "Success"
+        else:
+            job_status = "InProgress"
+
+        if len(info_data.get("MessageArgs")) > 0:
+            message_argument = str(info_data.get("MessageArgs")[0])
+        else:
+            message_argument = ""
+
+        transformed_info_data = {
+            "ElapsedTimeSinceCompletion": "",
+            "InstanceID": str(info_data.get("Id", NA)),
+            "JobStartTime": str(info_data.get("StartTime", NA)),
+            "JobStatus": job_state,
+            "JobUntilTime": "NA",
+            "Message": str(info_data.get("Message", NA)),
+            "MessageArguments": message_argument,
+            "MessageID": str(info_data.get("MessageId", NA)),
+            "Name": str(info_data.get("Name", NA)),
+            "PercentComplete": str(info_data.get("PercentComplete", NA)),
+            "Status": job_status,
+            "ActualRunningStopTime": str(info_data.get("ActualRunningStopTime", NA)),
+            "JobType": str(info_data.get("JobType", NA)),
+            "ActualRunningStartTime": str(info_data.get("ActualRunningStartTime", NA)),
+            "EndTime": str(info_data.get("EndTime", NA)),
+            "CompletionTime": str(info_data.get("CompletionTime", NA)),
+            "Description": str(info_data.get("Description", NA)),
+            "TargetSettingsURI": str(info_data.get("TargetSettingsURI", NA))
+        }
+        return transformed_info_data
+
+    def get_lifecycle_controller_job_details(self, job_id, members):
+        response = "Job ID is invalid"
+        for member in members:
+            if job_id in member.get(odata):
+                response = self.idrac.invoke_request(method='GET', uri=member.get(odata))
+                break
+        return response
+
+    def get_lifecycle_controller_job_list(self, job_id, jobs):
+        job_response = self.idrac.invoke_request(method='GET', uri=jobs)
+        members = job_response.json_data.get("Members", [])
+        response = self.get_lifecycle_controller_job_details(job_id, members)
+        return response
+
+    def get_lifecycle_controller_job_status_info(self, job_id):
+        manager_response = self.idrac.invoke_request(method='GET', uri=GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10)
+        jobs = manager_response.json_data.get("Oem", {}).get("Dell", {}).get("Jobs", {}).get(odata, "")
+        response = self.get_lifecycle_controller_job_list(job_id=job_id, jobs=jobs)
+        return response
diff --git a/plugins/modules/idrac_lifecycle_controller_job_status_info.py b/plugins/modules/idrac_lifecycle_controller_job_status_info.py
index c9376f4e2..6afa592ce 100644
--- a/plugins/modules/idrac_lifecycle_controller_job_status_info.py
+++ b/plugins/modules/idrac_lifecycle_controller_job_status_info.py
@@ -4,7 +4,7 @@
 #
 # Dell OpenManage Ansible Modules
 # Version 7.1.0
-# Copyright (C) 2018-2022 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright (C) 2018-2025 Dell Inc. or its subsidiaries. All Rights Reserved.
 
 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 #
@@ -32,6 +32,7 @@
 author:
     - "Rajeev Arakkal (@rajeevarakkal)"
     - "Anooja Vardhineni (@anooja-vardhineni)"
+    - "Trisha Datta (@trisha-dell)"
 notes:
     - Run this module from a system that has direct access to Dell iDRAC.
     - This module supports both IPv4 and IPv6 address for I(idrac_ip).
@@ -97,10 +98,21 @@
 
 
 import json
-from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac \
+    import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish \
+    import iDRACRedfishAPI
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.dellemc.openmanage.plugins.module_utils.\
+    idrac_utils.info.lifecycle_controller_job_status \
+    import IDRACLifecycleControllerJobStatusInfo
+from ansible_collections.dellemc.openmanage.plugins.module_utils.\
+    idrac_utils.info.firmware import IDRACFirmwareInfo
+
+ERR_STATUS = 404
+FETCH_MESSAGE = "Successfully fetched the job info."
 
 
 def main():
@@ -113,19 +125,41 @@ def main():
         supports_check_mode=True)
 
     try:
-        with iDRACConnection(module.params) as idrac:
-            job_id, msg = module.params.get('job_id'), {}
-            msg = idrac.job_mgr.get_job_status(job_id)
-            if msg.get('Status') == "Found Fault":
-                module.fail_json(msg="Job ID is invalid.")
+        with iDRACRedfishAPI(module.params) as idrac:
+            firmware_obj = IDRACFirmwareInfo(idrac)
+            if not firmware_obj.is_omsdk_required():
+                response = \
+                    IDRACLifecycleControllerJobStatusInfo(idrac). \
+                    get_lifecycle_controller_job_status_info(job_id=module.params["job_id"])
+                if response != "Job ID is invalid":
+                    lifecycle_controller_job_status_info = \
+                        IDRACLifecycleControllerJobStatusInfo(idrac). \
+                        transform_job_status_data(info_data=response.json_data)
+                else:
+                    module.exit_json(msg=FETCH_MESSAGE,
+                                     job_info={})
+            else:
+                with iDRACConnection(module.params) as idrac:
+                    job_id = module.params.get('job_id')
+                    lifecycle_controller_job_status_info = \
+                        idrac.job_mgr.get_job_status(job_id)
+                    if lifecycle_controller_job_status_info.get('Status') == "Found Fault":
+                        module.exit_json(msg=FETCH_MESSAGE,
+                                         job_info={})
     except HTTPError as err:
-        module.fail_json(msg=str(err), error_info=json.load(err))
+        module.exit_json(msg=str(err), error_info=json.load(err),
+                         failed=True)
     except URLError as err:
         module.exit_json(msg=str(err), unreachable=True)
-    except (RuntimeError, SSLValidationError, ConnectionError, KeyError,
-            ImportError, ValueError, TypeError) as e:
-        module.fail_json(msg=str(e))
-    module.exit_json(msg="Successfully fetched the job info", job_info=msg)
+    except (RuntimeError,
+            SSLValidationError,
+            IOError, ValueError,
+            TypeError,
+            ConnectionError) as e:
+        module.exit_json(msg=str(e), failed=True)
+
+    module.exit_json(msg="Successfully fetched the job info.",
+                     job_info=lifecycle_controller_job_status_info)
 
 
 if __name__ == '__main__':
diff --git a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/files/import_custom_failed.xml b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/files/import_custom_failed.xml
new file mode 100644
index 000000000..1f16ed438
--- /dev/null
+++ b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/files/import_custom_failed.xml
@@ -0,0 +1,5 @@
+<SystemConfiguration Model="" ServiceTag="" TimeStamp="">
+ <Component FQDD="iDRAC.Embedded.1">
+  <Attribute Name="RedfishEventing.1#DeliveryRetryIntervalInSeconds">1000</Attribute>
+ </Component>
+</SystemConfiguration>
\ No newline at end of file
diff --git a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/meta/main.yaml b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/meta/main.yaml
index db42312ab..ed97d539c 100644
--- a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/meta/main.yaml
+++ b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/meta/main.yaml
@@ -1,4 +1 @@
 ---
-dependencies:
-  - prepare_lifecycle_contoller_job_queue
-  - prepare_idrac_lifecycle_controller_status
diff --git a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/_job_details.yml b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/_job_details.yml
new file mode 100644
index 000000000..d2ad331ac
--- /dev/null
+++ b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/_job_details.yml
@@ -0,0 +1,68 @@
+---
+- block:
+    - name: Final url
+      ansible.builtin.set_fact:
+        job_url: "{{ base_uri }}{{ job_uri }}{{ JID }}"
+
+    - name: Get job details on iDRAC10
+      ansible.builtin.uri:
+        url: "{{ job_url }}"
+        user: "{{ idrac_user }}"
+        password: "{{ idrac_password }}"
+        force_basic_auth: true
+        validate_certs: false
+        method: GET
+        status_code: 200
+        headers: "Accept=application/json"
+        body_format: json
+        return_content: true
+      register: info_data
+      no_log: false
+
+    - name: Set job state
+      ansible.builtin.set_fact:
+        job_state: "{{ info_data.json.JobState | string }}"
+
+    - name: Set job state
+      ansible.builtin.set_fact:
+        job_success_list: ["Completed", "Success"]
+
+    - name: Set job state
+      ansible.builtin.set_fact:
+        job_failed_list: ["Failed", "Errors"]
+
+    - name: Determine job status
+      ansible.builtin.set_fact:
+        job_status: >-
+          {{ ('Success' if job_state in job_success_list else 'Failed' if
+          job_state in job_failed_list else 'Success' if 'Message' in
+          info_data.json and info_data.json.Message | string and
+          'completed' in info_data.json.Message |
+          string and 'errors' not in info_data.json.Message | string else
+          'InProgress') | trim }}
+
+    - name: Set fact for api_response
+      ansible.builtin.set_fact:
+        api_response:
+          ElapsedTimeSinceCompletion: ""
+          InstanceID: "{{ info_data.json.Id }}"
+          JobStartTime: "{{ info_data.json.StartTime }}"
+          JobStatus: "{{ job_state}}"
+          JobUntilTime: "NA"
+          Message: "{{ info_data.json.Message }}"
+          MessageArguments: "{{ (info_data.json.MessageArgs | default([]))[0] |
+            default('') }}"
+          MessageID: "{{ info_data.json.MessageId }}"
+          Name: "{{ info_data.json.Name }}"
+          PercentComplete: "{{ info_data.json.PercentComplete }}"
+          ActualRunningStopTime: "{{ info_data.json.ActualRunningStopTime |
+            default('None', true) }}"
+          JobType: "{{ info_data.json.JobType }}"
+          ActualRunningStartTime: "{{ info_data.json.ActualRunningStartTime }}"
+          EndTime: "{{ info_data.json.EndTime | default('None', true) }}"
+          CompletionTime: "{{ info_data.json.CompletionTime |
+            default('None', true) }}"
+          Description: "{{ info_data.json.Description }}"
+          Status: "{{ job_status }}"
+          TargetSettingsURI: "{{ info_data.json.TargetSettingsURI |
+            default('None', true)}}"
diff --git a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/invalid-11688.yaml b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/invalid-11688.yaml
index d6259a7fa..b9a737d14 100644
--- a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/invalid-11688.yaml
+++ b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/invalid-11688.yaml
@@ -18,27 +18,27 @@
         job_id: "1234"
       ignore_errors: true
       register: invalid_unreachable
+      ignore_unreachable: true
 
     - name: Verify task status - Negative - unreachable host
       ansible.builtin.assert:
         that:
-          - invalid_unreachable.failed
-          - 'invalid_unreachable.msg == "Unable to communicate with iDRAC
-           invalid. This may be due to one of the following:
-           Incorrect username or password, unreachable iDRAC IP or a
-           failure in TLS/SSL handshake."'
+          - invalid_unreachable.unreachable
+          - 'invalid_unreachable.msg == "<urlopen error [Errno -2] Name or
+           service not known>"'
 
     - name: Negative - invalid user
       dellemc.openmanage.idrac_lifecycle_controller_job_status_info:
         idrac_user: "invalid_user"
       ignore_errors: true
       register: invalid_user
+      ignore_unreachable: true
 
     - name: Verify task status - Negative - Invalid user
       ansible.builtin.assert:
         that:
           - invalid_user.failed
-          - invalid_user.msg == ""HTTP Error 401: Unauthorized"
+          - invalid_user.msg == "HTTP Error 401: Unauthorized"
 
     - name: Negative - invalid password
       dellemc.openmanage.idrac_lifecycle_controller_job_status_info:
@@ -50,7 +50,7 @@
       ansible.builtin.assert:
         that:
           - invalid_password.failed
-          - invalid_password.msg == ""HTTP Error 401: Unauthorized"
+          - invalid_password.msg == "HTTP Error 401: Unauthorized"
 
     - name: Negative - invalid ca_path
       dellemc.openmanage.idrac_lifecycle_controller_job_status_info:
@@ -63,7 +63,7 @@
       ansible.builtin.assert:
         that:
           - invalid_ca_path.failed
-          - invalid_ca_path.msg == ""HTTP Error 401: Unauthorized"
+          - invalid_ca_path.msg == "HTTP Error 401: Unauthorized"
 
   module_defaults:
     dellemc.openmanage.idrac_lifecycle_controller_job_status_info:
diff --git a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/job_status-11687.yaml b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/job_status-11687.yaml
index 6b8b25615..65345a25e 100644
--- a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/job_status-11687.yaml
+++ b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/tests/job_status-11687.yaml
@@ -1,33 +1,251 @@
 # Dell OpenManage Ansible modules
-# Copyright (C) 2024 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright (C) 2025 Dell Inc. or its subsidiaries. All Rights Reserved.
 
 # GNU General Public License v3.0+ (see COPYING or
 # https://www.gnu.org/licenses/gpl-3.0.txt)
 ---
 - name: Test that we have an iDRAC host, iDRAC username and iDRAC password
   ansible.builtin.fail:
-    msg: 'Please define the following variables: idrac_ip, idrac_user and
-     idrac_password.'
-  when: 'idrac_ip is not defined or idrac_user is not defined or idrac_password
-   is not defined'
+    msg: "Please define the following variables: idrac_ip, idrac_user and
+      idrac_password."
+  when: "idrac_ip is not defined or idrac_user is not defined or idrac_password
+    is not defined"
 
 - block:
-    - name: Export SCP to a local path and wait for this job to get completed.
+    - name: Get system resource api id
+      ansible.builtin.uri:
+        url: https://{{ idrac_ip }}:{{ idrac_port }}/redfish/v1/Systems
+        user: "{{ idrac_user }}"
+        password: "{{ idrac_password }}"
+        validate_certs: false
+      register: system_api_result
+
+    - name: Get first System Id from the system response
+      ansible.builtin.set_fact:
+        api_system: "{{ system_api_result.json.Members[0]['@odata.id'] |
+          default('') }}"
+        computer_system_id: "{{ system_api_result.json.Members[0]['@odata.id'] |
+          split('/') | last | default('System.Embedded.1') }}"
+
+    - name: Get system detail
+      ansible.builtin.uri:
+        url: https://{{ idrac_ip }}:{{ idrac_port }}{{ api_system }}
+        user: "{{ idrac_user }}"
+        password: "{{ idrac_password }}"
+        validate_certs: false
+      register: sys_detail
+
+    - name: Extracting iDRAC generation
+      ansible.builtin.set_fact:
+        idrac_gen: "{{ sys_detail.json.Oem.Dell.DellSystem.SystemGeneration }}"
+
+    - name: Export SCP for iDRAC8 and iDRAC9 to a local path and wait for this
+        job to get completed.
       idrac_server_config_profile:
         share_name: "{{ role_path }}/files"
         job_wait: true
       register: result_export_scp
+      when: idrac_gen != "17G Monolithic"
+
+    - name: Exrtact Export SCP Job ID
+      ansible.builtin.set_fact:
+        JID: "{{ result_export_scp.scp_status.Id }}"
+      when: idrac_gen != "17G Monolithic"
+
+    - name: Final url
+      ansible.builtin.set_fact:
+        final_url: "{{ base_uri }}{{ managers }}{{ export_scp }}"
+
+    - name: Create Success Export SCP Job on iDRAC10
+      ansible.builtin.uri: &idrac_export_scp_uri
+        url: "{{ final_url }}"
+        user: "{{ idrac_user }}"
+        password: "{{ idrac_password }}"
+        force_basic_auth: true
+        validate_certs: false
+        method: POST
+        body:
+          {
+            "ExportFormat": "JSON",
+            "ExportUse": "Default",
+            "ShareParameters": {"Target": ["IDRAC"]},
+          }
+        status_code: 202
+        headers: "Accept=application/json"
+        body_format: json
+        return_content: true
+      register: resp_export_scp
+      no_log: false
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Waiting for 30 seconds
+      ansible.builtin.wait_for:
+        timeout: 30
+
+    - name: Extract Export SCP Job ID on iDRAC10
+      ansible.builtin.set_fact:
+        JID: "{{ resp_export_scp.location.split('/')[-1] }}"
+      when: idrac_gen == "17G Monolithic"
 
     - name: Get Lifecycle Controller Job Status.
       idrac_lifecycle_controller_job_status_info:
-        job_id: "{{ result_export_scp.scp_status.Id }}"
-      register: result
+        idrac_ip: "{{ idrac_ip }}"
+        idrac_user: "{{ idrac_user }}"
+        idrac_password: "{{ idrac_password }}"
+        validate_certs: "{{ validate_certs }}"
+        job_id: "{{ JID }}"
+      register: lc_status
+      until:
+        - lc_status.job_info is defined
+        - lc_status.job_info.JobStatus in ["Completed", "Failed"]
+      retries: 10
+      delay: 30
+
+    - name: Get and construct job details
+      ansible.builtin.include_tasks: _job_details.yml
+      vars:
+        job_id: "{{ JID }}"
+      when: idrac_gen == "17G Monolithic"
 
     - name: Verify the status of tasks
-      assert:
+      ansible.builtin.assert:
+        that:
+          - not lc_status.changed
+          - lc_status.job_info.InstanceID == result_export_scp.scp_status.Id
+      when: idrac_gen != "17G Monolithic"
+
+    - name: Verify the diff for success tasks and uri status for iDRAC10
+      ansible.utils.fact_diff:
+        before: "{{ lc_status.job_info }}"
+        after: "{{ api_response }}"
+      register: diff_result
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Verify the complete status of tasks on iDRAC10
+      ansible.builtin.assert:
+        that:
+          - not lc_status.changed
+          - lc_status.job_info.InstanceID == JID
+          - resp_export_scp.status == 202
+          - not diff_result.changed
+          - not diff_result.diff_lines
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Create running export scp job on iDRAC10
+      ansible.builtin.uri:
+        <<: *idrac_export_scp_uri
+      register: reg_progress_exp
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Extract Export in running SCP Job ID on iDRAC10
+      ansible.builtin.set_fact:
+        JID: "{{ reg_progress_exp.location.split('/')[-1] }}"
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Get running Lifecycle Controller Job Status.
+      idrac_lifecycle_controller_job_status_info:
+        idrac_ip: "{{ idrac_ip }}"
+        idrac_user: "{{ idrac_user }}"
+        idrac_password: "{{ idrac_password }}"
+        validate_certs: "{{ validate_certs }}"
+        job_id: "{{ JID }}"
+      register: lc_status
+      until:
+        - lc_status.job_info is defined
+        - lc_status.job_info.JobStatus in ["Completed", "Failed", "Running"]
+      retries: 10
+      delay: 30
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Get and construct job details
+      ansible.builtin.include_tasks: _job_details.yml
+      vars:
+        job_id: "{{ JID }}"
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Verify the diff for running tasks and uri status in iDRAC10
+      ansible.utils.fact_diff:
+        before: "{{ lc_status.job_info }}"
+        after: "{{ api_response }}"
+      register: diff_result
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Verify the running status of tasks on iDRAC10
+      ansible.builtin.assert:
+        that:
+          - not lc_status.changed
+          - lc_status.job_info.InstanceID == JID
+          - resp_export_scp.status == 202
+          - not diff_result.changed
+          - not diff_result.diff_lines
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Wait for the job to get completed
+      ansible.builtin.pause:
+        seconds: 30
+
+    - name: Final url for import scp
+      ansible.builtin.set_fact:
+        final_url: "{{ base_uri }}{{ managers }}{{ import_scp }}"
+
+    - name: Create failed import scp job on iDRAC10
+      ansible.builtin.uri:
+        <<: *idrac_export_scp_uri
+        url: "{{ final_url }}"
+        body:
+          {
+            "ImportBuffer": "{{  lookup('ansible.builtin.file',
+              '{{ role_path }}/files/import_custom_failed.xml') }}",
+            "ShareParameters": {"Target": ["IDRAC"]},
+          }
+      when: idrac_gen == "17G Monolithic"
+      register: resp_import_scp
+
+    - name: Waiting for 30 seconds
+      ansible.builtin.wait_for:
+        timeout: 30
+
+    - name: Extract import SCP Job ID on iDRAC10
+      ansible.builtin.set_fact:
+        JID: "{{ resp_import_scp.location.split('/')[-1] }}"
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Get Lifecycle Controller Job Status of failed job.
+      idrac_lifecycle_controller_job_status_info:
+        idrac_ip: "{{ idrac_ip }}"
+        idrac_user: "{{ idrac_user }}"
+        idrac_password: "{{ idrac_password }}"
+        validate_certs: "{{ validate_certs }}"
+        job_id: "{{ JID }}"
+      register: lc_status
+      until:
+        - lc_status.job_info is defined
+        - lc_status.job_info.JobStatus in ["Completed", "Failed"]
+      retries: 10
+      delay: 30
+
+    - name: Get and construct job details
+      ansible.builtin.include_tasks: _job_details.yml
+      vars:
+        job_id: "{{ JID }}"
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Verify the diff for failed tasks and uri status in iDRAC10
+      ansible.utils.fact_diff:
+        before: "{{ lc_status.job_info }}"
+        after: "{{ api_response }}"
+      register: diff_result
+      when: idrac_gen == "17G Monolithic"
+
+    - name: Verify the status of failed tasks on iDRAC10
+      ansible.builtin.assert:
         that:
-          - not result.changed
-          - result.job_info.InstanceID == result_export_scp.scp_status.Id
+          - not lc_status.changed
+          - lc_status.job_info.InstanceID == JID
+          - resp_import_scp.status == 202
+          - not diff_result.changed
+          - not diff_result.diff_lines
+      when: idrac_gen == "17G Monolithic"
 
   module_defaults:
     dellemc.openmanage.idrac_lifecycle_controller_job_status_info:
diff --git a/tests/integration/targets/idrac_lifecycle_controller_job_status_info/vars/main.yaml b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/vars/main.yaml
new file mode 100644
index 000000000..8fa061db4
--- /dev/null
+++ b/tests/integration/targets/idrac_lifecycle_controller_job_status_info/vars/main.yaml
@@ -0,0 +1,6 @@
+---
+base_uri: "https://{{ idrac_ip }}:{{ idrac_port }}/redfish/v1/"
+job_uri: "Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/"
+managers: "Managers/iDRAC.Embedded.1/Actions/Oem/"
+export_scp: "OemManager.ExportSystemConfiguration"
+import_scp: "OemManager.ImportSystemConfiguration"
diff --git a/tests/unit/plugins/module_utils/idrac_utils/test_idrac_lifecycle_controller_job_status_info_utils.py b/tests/unit/plugins/module_utils/idrac_utils/test_idrac_lifecycle_controller_job_status_info_utils.py
new file mode 100644
index 000000000..48f09a12b
--- /dev/null
+++ b/tests/unit/plugins/module_utils/idrac_utils/test_idrac_lifecycle_controller_job_status_info_utils.py
@@ -0,0 +1,331 @@
+from ansible_collections.dellemc.openmanage.tests.unit.plugins.\
+    module_utils.idrac_utils.test_idrac_utils import TestUtils
+from ansible_collections.dellemc.openmanage.plugins.\
+    module_utils.idrac_utils.info.lifecycle_controller_job_status import IDRACLifecycleControllerJobStatusInfo
+from unittest.mock import MagicMock
+
+MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.'
+JOB_LINK = "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id"
+JOB_MEMBERS = [
+    {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id"
+    },
+]
+RESPONSE = {
+    "Status": {
+        "Health": "OK",
+        "State": "Enabled"
+    },
+    "LastResetTime": "2025-04-15T05:34:47-05:00",
+    "DateTime": "2025-04-15T09:39:04-05:00",
+    "PowerState": "On",
+    "GraphicalConsole": {
+        "ServiceEnabled": True,
+        "ConnectTypesSupported": [
+            "KVMIP"
+        ],
+        "ConnectTypesSupported@odata.count": 1,
+        "MaxConcurrentSessions": 6
+    },
+    "SerialConsole": {
+        "ServiceEnabled": False,
+        "ConnectTypesSupported": [
+        ],
+        "ConnectTypesSupported@odata.count": 0,
+        "MaxConcurrentSessions": 0
+    },
+    "SerialNumber": "CNWS3004A700O2",
+    "LogServices": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/LogServices"
+    },
+    "DateTimeLocalOffset": "-05:00",
+    "Certificates": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Certificates"
+    },
+    "EthernetInterfaces": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces"
+    },
+    "TimeZoneName": "CST6CDT",
+    "ServiceIdentification": "DN04203",
+    "Model": "17G Monolithic",
+    "Name": "Manager",
+    "@odata.type": "#Manager.v1_20_0.Manager",
+    "Oem": {
+        "Dell": {
+            "Jobs": {
+                "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs"
+            },
+        }
+    },
+    "PartNumber": "03TJR3",
+    "ManagerType": "BMC",
+    "Redundancy@odata.count": 0,
+    "ManagerDiagnosticData": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/ManagerDiagnosticData"
+    },
+    "Id": "iDRAC.Embedded.1"
+}
+JOB_RESPONSE = {
+    "Description": "Job Instance",
+    "MessageId": "RED106",
+    "Message": "Unable to parse the lc_validator_output.xml file because of an internal error.",
+    "Name": "update:new",
+    "StartTime": "2025-04-15T06:01:03",
+    "ActualRunningStopTime": None,
+    "@odata.etag": "W/\"gen-31\"",
+    "Id": "job_id",
+    "EndTime": None,
+    "PercentComplete": 100,
+    "JobType": "FirmwareUpdate",
+    "MessageArgs": [],
+    "MessageArgs@odata.count": 0,
+    "JobState": "Failed",
+    "ActualRunningStartTime": None,
+    "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id",
+    "TargetSettingsURI": None,
+    "@odata.type": "#DellJob.v1_6_0.DellJob",
+    "CompletionTime": "2025-04-15T06:01:14",
+    "@odata.context": "/redfish/v1/$metadata#DellJob.DellJob"
+}
+
+
+class TestLcJobStatus(TestUtils):
+
+    def test_get_lifecycle_controller_job_status_info(self, idrac_mock):
+        idrac_mock.invoke_request.return_value.json_data = RESPONSE
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        idrac_lc_job_status_info.get_lifecycle_controller_job_list = \
+            MagicMock(return_value=JOB_RESPONSE)
+        result = idrac_lc_job_status_info.get_lifecycle_controller_job_status_info(job_id="job_id")
+        expected_result = {
+            '@odata.context': '/redfish/v1/$metadata#DellJob.DellJob',
+            '@odata.etag': 'W/"gen-31"',
+            '@odata.id': '/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id',
+            '@odata.type': '#DellJob.v1_6_0.DellJob',
+            'ActualRunningStartTime': None,
+            'ActualRunningStopTime': None,
+            'CompletionTime': '2025-04-15T06:01:14',
+            'Description': 'Job Instance',
+            'EndTime': None,
+            'Id': 'job_id',
+            'JobState': 'Failed',
+            'JobType': 'FirmwareUpdate',
+            'Message': 'Unable to parse the lc_validator_output.xml file because of an internal '
+            'error.',
+            'MessageArgs': [],
+            'MessageArgs@odata.count': 0,
+            'MessageId': 'RED106',
+            'Name': 'update:new',
+            'PercentComplete': 100,
+            'StartTime': '2025-04-15T06:01:03',
+            'TargetSettingsURI': None,
+        }
+        assert result == expected_result
+
+    def test_get_lifecycle_controller_job_list(self, idrac_mock):
+        JOB_LIST_RESPONSE = {
+            "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs",
+            "@odata.etag": "W/\"gen-1\"",
+            "@odata.context": "/redfish/v1/$metadata#DellJobCollection.DellJobCollection",
+            "@odata.type": "#DellJobCollection.DellJobCollection",
+            "Description": "Collection of Job Instances",
+            "Members": [
+                {
+                    "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id"
+                }
+            ],
+            "Members@odata.count": 1,
+            "Name": "JobQueue"
+        }
+        idrac_mock.invoke_request.return_value.json_data = JOB_LIST_RESPONSE
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        idrac_lc_job_status_info.get_lifecycle_controller_job_details = \
+            MagicMock(return_value=JOB_RESPONSE)
+        result = idrac_lc_job_status_info.get_lifecycle_controller_job_list(
+            job_id="job_id",
+            jobs=RESPONSE["Oem"]["Dell"]["Jobs"]["@odata.id"])
+        expected_result = {
+            '@odata.context': '/redfish/v1/$metadata#DellJob.DellJob',
+            '@odata.etag': 'W/"gen-31"',
+            '@odata.id': '/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id',
+            '@odata.type': '#DellJob.v1_6_0.DellJob',
+            'ActualRunningStartTime': None,
+            'ActualRunningStopTime': None,
+            'CompletionTime': '2025-04-15T06:01:14',
+            'Description': 'Job Instance',
+            'EndTime': None,
+            'Id': 'job_id',
+            'JobState': 'Failed',
+            'JobType': 'FirmwareUpdate',
+            'Message': 'Unable to parse the lc_validator_output.xml file because of an internal '
+            'error.',
+            'MessageArgs': [],
+            'MessageArgs@odata.count': 0,
+            'MessageId': 'RED106',
+            'Name': 'update:new',
+            'PercentComplete': 100,
+            'StartTime': '2025-04-15T06:01:03',
+            'TargetSettingsURI': None,
+        }
+        assert result == expected_result
+
+    def test_get_lifecycle_controller_job_details(self, idrac_mock):
+        JOB_MEMBERS_RESPONSE = [
+            {
+                "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id"
+            }
+        ]
+        idrac_mock.invoke_request.return_value = JOB_RESPONSE
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        result = idrac_lc_job_status_info.get_lifecycle_controller_job_details(
+            job_id="job_id",
+            members=JOB_MEMBERS_RESPONSE)
+        expected_result = {
+            '@odata.context': '/redfish/v1/$metadata#DellJob.DellJob',
+            '@odata.etag': 'W/"gen-31"',
+            '@odata.id': '/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id',
+            '@odata.type': '#DellJob.v1_6_0.DellJob',
+            'ActualRunningStartTime': None,
+            'ActualRunningStopTime': None,
+            'CompletionTime': '2025-04-15T06:01:14',
+            'Description': 'Job Instance',
+            'EndTime': None,
+            'Id': 'job_id',
+            'JobState': 'Failed',
+            'JobType': 'FirmwareUpdate',
+            'Message': 'Unable to parse the lc_validator_output.xml file because of an internal '
+            'error.',
+            'MessageArgs': [],
+            'MessageArgs@odata.count': 0,
+            'MessageId': 'RED106',
+            'Name': 'update:new',
+            'PercentComplete': 100,
+            'StartTime': '2025-04-15T06:01:03',
+            'TargetSettingsURI': None,
+        }
+        assert result == expected_result
+
+    def test_get_lifecycle_controller_job_status_info_success(self, idrac_mock):
+        JOB_SUCCESS_RESPONSE = {
+            "Description": "Job Instance",
+            "MessageId": "RED106",
+            "Message": "Job is successful",
+            "Name": "update:new",
+            "StartTime": "2025-04-15T06:01:03",
+            "ActualRunningStopTime": None,
+            "@odata.etag": "W/\"gen-31\"",
+            "Id": "job_id",
+            "EndTime": None,
+            "PercentComplete": 100,
+            "JobType": "FirmwareUpdate",
+            "MessageArgs": ["Successfully updated the firmware"],
+            "MessageArgs@odata.count": 0,
+            "JobState": "Success",
+            "ActualRunningStartTime": None,
+            "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id",
+            "TargetSettingsURI": None,
+            "@odata.type": "#DellJob.v1_6_0.DellJob",
+            "CompletionTime": "2025-04-15T06:01:14",
+            "@odata.context": "/redfish/v1/$metadata#DellJob.DellJob"
+        }
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        idrac_lc_job_status_info.get_lifecycle_controller_job_status_info = \
+            MagicMock(return_value=JOB_SUCCESS_RESPONSE)
+        result = idrac_lc_job_status_info.transform_job_status_data(info_data=JOB_SUCCESS_RESPONSE)
+        expected_result = {
+            "Description": "Job Instance",
+            "MessageID": "RED106",
+            "Message": "Job is successful",
+            "Name": "update:new",
+            "JobStartTime": "2025-04-15T06:01:03",
+            "ActualRunningStopTime": "None",
+            "InstanceID": "job_id",
+            "EndTime": "None",
+            "PercentComplete": "100",
+            "JobType": "FirmwareUpdate",
+            "MessageArguments": "Successfully updated the firmware",
+            "JobStatus": "Success",
+            "ActualRunningStartTime": "None",
+            "TargetSettingsURI": "None",
+            "CompletionTime": "2025-04-15T06:01:14",
+            "ElapsedTimeSinceCompletion": "",
+            "JobUntilTime": "NA",
+            "Status": "Success"
+        }
+        assert result == expected_result
+
+    def test_get_lifecycle_controller_job_status_info_failed(self, idrac_mock):
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        idrac_lc_job_status_info.get_lifecycle_controller_job_status_info = \
+            MagicMock(return_value=JOB_RESPONSE)
+        result = idrac_lc_job_status_info.transform_job_status_data(info_data=JOB_RESPONSE)
+        expected_result = {
+            "Description": "Job Instance",
+            "MessageID": "RED106",
+            "Message": "Unable to parse the lc_validator_output.xml file because of an internal error.",
+            "Name": "update:new",
+            "JobStartTime": "2025-04-15T06:01:03",
+            "ActualRunningStopTime": "None",
+            "InstanceID": "job_id",
+            "EndTime": "None",
+            "PercentComplete": "100",
+            "JobType": "FirmwareUpdate",
+            "MessageArguments": "",
+            "JobStatus": "Failed",
+            "ActualRunningStartTime": "None",
+            "TargetSettingsURI": "None",
+            "CompletionTime": "2025-04-15T06:01:14",
+            "ElapsedTimeSinceCompletion": "",
+            "JobUntilTime": "NA",
+            "Status": "Failed"
+        }
+        assert result == expected_result
+
+    def test_get_lifecycle_controller_job_status_info_pending(self, idrac_mock):
+        JOB_PENDING_RESPONSE = {
+            "Description": "Job Instance",
+            "MessageId": "RED106",
+            "Message": "Job is in running state",
+            "Name": "update:new",
+            "StartTime": "2025-04-15T06:01:03",
+            "ActualRunningStopTime": None,
+            "@odata.etag": "W/\"gen-31\"",
+            "Id": "job_id",
+            "EndTime": None,
+            "PercentComplete": 80,
+            "JobType": "FirmwareUpdate",
+            "MessageArgs": [],
+            "MessageArgs@odata.count": 0,
+            "JobState": "Pending",
+            "ActualRunningStartTime": None,
+            "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id",
+            "TargetSettingsURI": None,
+            "@odata.type": "#DellJob.v1_6_0.DellJob",
+            "CompletionTime": "",
+            "@odata.context": "/redfish/v1/$metadata#DellJob.DellJob"
+        }
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        idrac_lc_job_status_info.get_lifecycle_controller_job_status_info = MagicMock(
+            return_value=JOB_PENDING_RESPONSE)
+        result = idrac_lc_job_status_info.transform_job_status_data(info_data=JOB_PENDING_RESPONSE)
+        expected_result = {
+            "Description": "Job Instance",
+            "MessageID": "RED106",
+            "Message": "Job is in running state",
+            "Name": "update:new",
+            "JobStartTime": "2025-04-15T06:01:03",
+            "ActualRunningStopTime": "None",
+            "InstanceID": "job_id",
+            "EndTime": "None",
+            "PercentComplete": "80",
+            "JobType": "FirmwareUpdate",
+            "MessageArguments": "",
+            "JobStatus": "Pending",
+            "ActualRunningStartTime": "None",
+            "TargetSettingsURI": "None",
+            "CompletionTime": "",
+            "ElapsedTimeSinceCompletion": "",
+            "JobUntilTime": "NA",
+            "Status": "InProgress"
+        }
+        assert result == expected_result
diff --git a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
index cabe36425..6e4cb838a 100644
--- a/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
+++ b/tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
@@ -3,7 +3,7 @@
 #
 # Dell OpenManage Ansible Modules
 # Version 7.0.0
-# Copyright (C) 2020-2022 Dell Inc. or its subsidiaries. All Rights Reserved.
+# Copyright (C) 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved.
 
 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 #
@@ -15,7 +15,9 @@
 import json
 from ansible_collections.dellemc.openmanage.plugins.modules import idrac_lifecycle_controller_job_status_info
 from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule
-from unittest.mock import MagicMock, PropertyMock
+from unittest.mock import MagicMock, Mock
+from ansible_collections.dellemc.openmanage.plugins.\
+    module_utils.idrac_utils.info.lifecycle_controller_job_status import IDRACLifecycleControllerJobStatusInfo
 from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from io import StringIO
@@ -26,6 +28,89 @@
 importorskip("omsdk.sdkcreds")
 
 MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.'
+JOB_MEMBERS = [
+    {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id"
+    },
+]
+JOB_LINK = "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id"
+RESPONSE = {
+    "Status": {
+        "Health": "OK",
+        "State": "Enabled"
+    },
+    "LastResetTime": "2025-04-15T05:34:47-05:00",
+    "DateTime": "2025-04-15T09:39:04-05:00",
+    "PowerState": "On",
+    "GraphicalConsole": {
+        "ServiceEnabled": True,
+        "ConnectTypesSupported": [
+            "KVMIP"
+        ],
+        "ConnectTypesSupported@odata.count": 1,
+        "MaxConcurrentSessions": 6
+    },
+    "SerialConsole": {
+        "ServiceEnabled": False,
+        "ConnectTypesSupported": [
+        ],
+        "ConnectTypesSupported@odata.count": 0,
+        "MaxConcurrentSessions": 0
+    },
+    "SerialNumber": "CNWS3004A700O2",
+    "LogServices": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/LogServices"
+    },
+    "TimeZoneName": "CST6CDT",
+    "ServiceIdentification": "DN04203",
+    "Model": "17G Monolithic",
+    "Name": "Manager",
+    "DateTimeLocalOffset": "-05:00",
+    "Certificates": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Certificates"
+    },
+    "EthernetInterfaces": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces"
+    },
+    "@odata.type": "#Manager.v1_20_0.Manager",
+    "Oem": {
+        "Dell": {
+            "Jobs": {
+                "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs"
+            },
+        }
+    },
+    "PartNumber": "03TJR3",
+    "ManagerType": "BMC",
+    "Redundancy@odata.count": 0,
+    "ManagerDiagnosticData": {
+        "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/ManagerDiagnosticData"
+    },
+    "Id": "iDRAC.Embedded.1"
+}
+
+JOB_RESPONSE = {
+    "ActualRunningStopTime": None,
+    "@odata.etag": "W/\"gen-31\"",
+    "Id": "job_id",
+    "EndTime": None,
+    "PercentComplete": 100,
+    "Description": "Job Instance",
+    "MessageId": "RED106",
+    "Message": "Unable to parse the lc_validator_output.xml file because of an internal error.",
+    "Name": "update:new",
+    "StartTime": "2025-04-15T06:01:03",
+    "JobType": "FirmwareUpdate",
+    "MessageArgs": [],
+    "MessageArgs@odata.count": 0,
+    "JobState": "Failed",
+    "ActualRunningStartTime": None,
+    "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id",
+    "TargetSettingsURI": None,
+    "@odata.type": "#DellJob.v1_6_0.DellJob",
+    "CompletionTime": "2025-04-15T06:01:14",
+    "@odata.context": "/redfish/v1/$metadata#DellJob.DellJob"
+}
 
 
 class TestLcJobStatus(FakeAnsibleModule):
@@ -36,9 +121,25 @@ def idrac_mock(self, mocker):
         omsdk_mock = MagicMock()
         idrac_obj = MagicMock()
         omsdk_mock.job_mgr = idrac_obj
-        type(idrac_obj).get_job_status = PropertyMock(return_value="job_id")
+        type(idrac_obj).get_job_status = Mock(return_value="job_id")
+        return idrac_obj
+
+    @pytest.fixture
+    def idrac_lc_job_status_info_mock(self):
+        omsdk_mock = MagicMock()
+        idrac_obj = MagicMock()
+        omsdk_mock.get_entityjson = idrac_obj
+        type(idrac_obj).get_json_device = Mock(return_value="msg")
         return idrac_obj
 
+    @pytest.fixture
+    def idrac_lc_job_status_info_connection_mock(self, mocker, idrac_lc_job_status_info_mock):
+        idrac_redfish_conn_class_mock = mocker.patch(MODULE_PATH +
+                                                     'idrac_lifecycle_controller_job_status_info.iDRACRedfishAPI',
+                                                     return_value=idrac_lc_job_status_info_mock)
+        idrac_redfish_conn_class_mock.return_value.__enter__.return_value = idrac_lc_job_status_info_mock
+        return idrac_lc_job_status_info_mock
+
     @pytest.fixture
     def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock = mocker.patch(MODULE_PATH +
@@ -47,32 +148,145 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_lc_job_status_info_mock,
+                                                         idrac_lc_job_status_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_lc_job_status_info_mock.get_entityjson.return_value = None
+        idrac_lc_job_status_info_connection_mock.get_json_device.return_value = ""
+        idrac_lc_job_status_info_connection_mock.invoke_request.side_effect = exc_type(
+            'https://testhost.com', 404,
+            'http error message',
+            {"accept-type": "application/json"},
+            StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         exc_type,
+                                                         idrac_lc_job_status_info_mock,
+                                                         idrac_lc_job_status_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_lc_job_status_info_mock.get_entityjson.return_value = None
+        idrac_lc_job_status_info_connection_mock.get_json_device.return_value = ""
+        idrac_lc_job_status_info_connection_mock.invoke_request.side_effect = exc_type(
+            'https://testhost.com', 404,
+            'http error message',
+            {"accept-type": "application/json"},
+            StringIO(json_str))
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Found Fault"}
+        result = self._run_module(idrac_default_args)
+        assert result == {
+            "msg": "Successfully fetched the job info.",
+            "job_info": {},
+            "changed": False}
+
+    def test_get_lifecycle_controller_job_status_info_case02(
+            self,
+            idrac_default_args,
+            idrac_mock,
+            mocker):
+        idrac_default_args.update({"job_id": "job_id"})
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info.IDRACFirmwareInfo.is_omsdk_required",
+                     return_value=False)
+        idrac_mock.invoke_request.return_value.status_code = 200
+        response1 = MagicMock()
+        response1.json_data = {"status": "Success"}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info.IDRACLifecycleControllerJobStatusInfo.get_lifecycle_controller_job_status_info",
+                     return_value=response1)
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info.IDRACLifecycleControllerJobStatusInfo.transform_job_status_data",
+                     return_value={"status": "Success"})
+        result = self._run_module(idrac_default_args)
+        assert result == {
+            "job_info": {"status": "Success"},
+            "msg": "Successfully fetched the job info.",
+            "changed": False}
+
+    def test_get_lifecycle_controller_job_status_info_invalid_id(
+            self,
+            idrac_default_args,
+            idrac_mock,
+            mocker):
+        idrac_default_args.update({"job_id": "job_id"})
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info.IDRACFirmwareInfo.is_omsdk_required",
+                     return_value=False)
+        idrac_mock.invoke_request.return_value.status_code = 200
+        response1 = "Job ID is invalid"
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info.IDRACLifecycleControllerJobStatusInfo.get_lifecycle_controller_job_status_info",
+                     return_value=response1)
+        result = self._run_module(idrac_default_args)
+        assert result == {
+            "msg": "Successfully fetched the job info.",
+            "job_info": {},
+            "changed": False}
+
+    def test_get_lifecycle_controller_job_status_info(self, idrac_mock, idrac_default_args):
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_mock.invoke_request.return_value.json_data = RESPONSE
+        idrac_lc_job_status_info = IDRACLifecycleControllerJobStatusInfo(idrac_mock)
+        idrac_lc_job_status_info.get_lifecycle_controller_job_list = \
+            MagicMock(return_value=JOB_RESPONSE)
+        result = idrac_lc_job_status_info.get_lifecycle_controller_job_status_info(job_id="job_id")
+        expected_result = {
+            '@odata.context': '/redfish/v1/$metadata#DellJob.DellJob',
+            '@odata.etag': 'W/"gen-31"',
+            '@odata.id': '/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/job_id',
+            '@odata.type': '#DellJob.v1_6_0.DellJob',
+            'ActualRunningStartTime': None,
+            'ActualRunningStopTime': None,
+            'CompletionTime': '2025-04-15T06:01:14',
+            'JobType': 'FirmwareUpdate',
+            'Description': 'Job Instance',
+            'EndTime': None,
+            'Id': 'job_id',
+            'JobState': 'Failed',
+            'Message': 'Unable to parse the lc_validator_output.xml file because of an internal '
+            'error.',
+            'MessageArgs': [],
+            'MessageArgs@odata.count': 0,
+            'MessageId': 'RED106',
+            'Name': 'update:new',
+            'PercentComplete': 100,
+            'StartTime': '2025-04-15T06:01:03',
+            'TargetSettingsURI': None,
+        }
+        assert result == expected_result
+
     @pytest.mark.parametrize("exc_type", [SSLValidationError, URLError, ValueError, TypeError,
                                           ConnectionError, HTTPError])
-    def test_main_exception_handling_case(self, exc_type, mocker, idrac_get_lc_job_status_connection_mock,
+    def test_main_exception_handling_case(self, exc_type, mocker, idrac_lc_job_status_info_connection_mock,
                                           idrac_default_args):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
         idrac_default_args.update({"job_id": "job_id"})
         json_str = to_text(json.dumps({"data": "out"}))
-        if exc_type == URLError:
-            idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.side_effect = exc_type("url open error")
+        if exc_type not in [HTTPError, SSLValidationError]:
+            idrac_lc_job_status_info_connection_mock.invoke_request.side_effect = exc_type("exception message")
+        elif exc_type in [URLError]:
+            idrac_lc_job_status_info_connection_mock.invoke_request.side_effect = exc_type("exception message")
+        else:
+            idrac_lc_job_status_info_connection_mock.invoke_request.side_effect = exc_type(
+                'https://testhost.com', 400,
+                'http error message',
+                {"accept-type": "application/json"},
+                StringIO(json_str))
+        if exc_type != URLError:
             result = self._run_module(idrac_default_args)
-            assert result["unreachable"] is True
-        elif exc_type not in [HTTPError, SSLValidationError]:
-            idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.side_effect = exc_type("exception message")
-            result = self._run_module_with_fail_json(idrac_default_args)
             assert result['failed'] is True
         else:
-            idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.side_effect = exc_type('https://testhost.com', 400,
-                                                                                                  'http error message',
-                                                                                                  {"accept-type": "application/json"},
-                                                                                                  StringIO(json_str))
-            result = self._run_module_with_fail_json(idrac_default_args)
-            assert result['failed'] is True
+            result = self._run_module(idrac_default_args)
         assert 'msg' in result


Reviews:
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T05:55:42Z
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T05:58:45Z
user: login: sachin-apa
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T06:16:32Z
user: login: sachin-apa
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T12:42:08Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T15:31:28Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T15:31:45Z
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T03:52:59Z
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T03:55:16Z
user: login: ABHISHEK-SINHA10
body: Please take care of given PR comments.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T07:50:16Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T10:51:26Z
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T05:09:58Z
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-18T04:40:56Z
user: login: ABHISHEK-SINHA10
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-18T04:41:04Z
user: login: Kritika-Bhateja-03
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T11:54:37Z
user: login: Saksham-Nautiyal
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T14:43:13Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:45:17Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:45:22Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:46:57Z
user: login: trisha-dell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:47:05Z
user: login: Saksham-Nautiyal
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:58:50Z
user: login: Kritika-Bhateja-03
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T17:04:04Z

Review comments:
diff_hunk: @@ -47,32 +63,187 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_redfish_system_info_connection_mock.invoke_request.side_effect = exc_type('https://testhost.com', 404,
+                                                                                        'http error message',
+                                                                                        {"accept-type": "application/json"},
+                                                                                        StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    def test_main_idrac_get_lc_job_status_success_case02(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        # Scenario 1: run and accept_eula both as true
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Completed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": ["NA"],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
+
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        # Scenario 1: run and accept_eula both as true
path: tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
user: login: ABHISHEK-SINHA10
body: is this comment applicable to this test scenario?
created_at: 2025-04-07T05:55:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,10 +99,84 @@
 
 import json
 from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10
+from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from ansible.module_utils.basic import AnsibleModule
 
+ERR_STATUS = 404
+
+
+def get_from_wsman(module):
+    with iDRACConnection(module.params) as idrac:
+        job_id, msg = module.params.get('job_id'), {}
+        msg = idrac.job_mgr.get_job_status(job_id)
+        if msg.get('Status') == "Found Fault":
+            module.exit_json(msg="Job ID is invalid.", failed=True)
+    return msg
+
+
+def transform_job_status_data(info_data):
+    transformed_data = []
+
+    job_success_list = ['Completed', 'Success']
+    job_failed_list = ['Failed', 'Errors']
+    job_state = str(info_data.get("JobState"))
+    if job_state in job_success_list:
+        job_status = "Success"
+    elif job_state in job_failed_list:
+        job_status = "Failed"
+    elif 'Message' in info_data and str(info_data.get("Message")) and \
+            'completed' in str(info_data.get("Message")) and \
+            'errors' not in str(info_data.get("Message")):
+        job_status = "Success"
+    else:
+        job_status = "InProgress"
+
+    if len(info_data.get("MessageArgs")) > 0:
+        message_argument = str(info_data.get("MessageArgs")[0])
+    else:
+        message_argument = ""
+
+    transformed_info_data = {
+        "ElapsedTimeSinceCompletion": "",
+        "InstanceID": str(info_data.get("Id")),
+        "JobStartTime": str(info_data.get("StartTime")),
+        "JobStatus": job_state,
+        "JobUntilTime": "NA",
+        "Message": str(info_data.get("Message")),
+        "MessageArguments": message_argument,
+        "MessageID": str(info_data.get("MessageId")),
+        "Name": str(info_data.get("Name")),
+        "PercentComplete": str(info_data.get("PercentComplete")),
+        "Status": job_status,
+        "ActualRunningStopTime": str(info_data.get("ActualRunningStopTime")),
+        "JobType": str(info_data.get("JobType")),
+        "ActualRunningStartTime": str(info_data.get("ActualRunningStartTime")),
+        "EndTime": str(info_data.get("EndTime")),
+        "CompletionTime": str(info_data.get("CompletionTime")),
+        "Description": str(info_data.get("Description")),
+        "TargetSettingsURI": str(info_data.get("TargetSettingsURI"))
+    }
+    transformed_data.append(transformed_info_data)
+
+    return transformed_data
+
+
+def get_lifecycle_controller_job_status_info(idrac, module):
+    try:
+        response = idrac.invoke_request(method='GET', uri=GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10.format(module.params.get('job_id')))
path: plugins/modules/idrac_lifecycle_controller_job_status_info.py
user: login: ABHISHEK-SINHA10
body: please make API fetching dynamic, do not hardcode the API, as we have been following in other new modules.
created_at: 2025-04-07T05:58:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,10 +99,84 @@
 
 import json
 from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10
+from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from ansible.module_utils.basic import AnsibleModule
 
+ERR_STATUS = 404
+
+
+def get_from_wsman(module):
+    with iDRACConnection(module.params) as idrac:
+        job_id, msg = module.params.get('job_id'), {}
+        msg = idrac.job_mgr.get_job_status(job_id)
+        if msg.get('Status') == "Found Fault":
+            module.exit_json(msg="Job ID is invalid.", failed=True)
+    return msg
+
+
+def transform_job_status_data(info_data):
+    transformed_data = []
+
+    job_success_list = ['Completed', 'Success']
+    job_failed_list = ['Failed', 'Errors']
+    job_state = str(info_data.get("JobState"))
+    if job_state in job_success_list:
+        job_status = "Success"
+    elif job_state in job_failed_list:
+        job_status = "Failed"
+    elif 'Message' in info_data and str(info_data.get("Message")) and \
+            'completed' in str(info_data.get("Message")) and \
+            'errors' not in str(info_data.get("Message")):
+        job_status = "Success"
+    else:
+        job_status = "InProgress"
+
+    if len(info_data.get("MessageArgs")) > 0:
+        message_argument = str(info_data.get("MessageArgs")[0])
+    else:
+        message_argument = ""
+
+    transformed_info_data = {
+        "ElapsedTimeSinceCompletion": "",
+        "InstanceID": str(info_data.get("Id")),
+        "JobStartTime": str(info_data.get("StartTime")),
+        "JobStatus": job_state,
+        "JobUntilTime": "NA",
+        "Message": str(info_data.get("Message")),
+        "MessageArguments": message_argument,
+        "MessageID": str(info_data.get("MessageId")),
+        "Name": str(info_data.get("Name")),
+        "PercentComplete": str(info_data.get("PercentComplete")),
+        "Status": job_status,
+        "ActualRunningStopTime": str(info_data.get("ActualRunningStopTime")),
+        "JobType": str(info_data.get("JobType")),
+        "ActualRunningStartTime": str(info_data.get("ActualRunningStartTime")),
+        "EndTime": str(info_data.get("EndTime")),
+        "CompletionTime": str(info_data.get("CompletionTime")),
+        "Description": str(info_data.get("Description")),
+        "TargetSettingsURI": str(info_data.get("TargetSettingsURI"))
+    }
+    transformed_data.append(transformed_info_data)
+
+    return transformed_data
+
+
+def get_lifecycle_controller_job_status_info(idrac, module):
+    try:
+        response = idrac.invoke_request(method='GET', uri=GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10.format(module.params.get('job_id')))
+        if response.status_code == 200:
+            transformed_job_status_data = transform_job_status_data(response.json_data)
+            return transformed_job_status_data
path: plugins/modules/idrac_lifecycle_controller_job_status_info.py
user: login: sachin-apa
body: This would be most called API for all the modules to get the job details for tracking i believe, is there a way we can move this to utils ?
created_at: 2025-04-07T06:08:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,10 +99,84 @@
 
 import json
 from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10
+from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from ansible.module_utils.basic import AnsibleModule
 
+ERR_STATUS = 404
+
+
+def get_from_wsman(module):
+    with iDRACConnection(module.params) as idrac:
+        job_id, msg = module.params.get('job_id'), {}
+        msg = idrac.job_mgr.get_job_status(job_id)
+        if msg.get('Status') == "Found Fault":
+            module.exit_json(msg="Job ID is invalid.", failed=True)
+    return msg
+
+
+def transform_job_status_data(info_data):
+    transformed_data = []
+
+    job_success_list = ['Completed', 'Success']
+    job_failed_list = ['Failed', 'Errors']
+    job_state = str(info_data.get("JobState"))
+    if job_state in job_success_list:
+        job_status = "Success"
+    elif job_state in job_failed_list:
+        job_status = "Failed"
+    elif 'Message' in info_data and str(info_data.get("Message")) and \
+            'completed' in str(info_data.get("Message")) and \
+            'errors' not in str(info_data.get("Message")):
+        job_status = "Success"
+    else:
+        job_status = "InProgress"
+
+    if len(info_data.get("MessageArgs")) > 0:
+        message_argument = str(info_data.get("MessageArgs")[0])
+    else:
+        message_argument = ""
+
+    transformed_info_data = {
+        "ElapsedTimeSinceCompletion": "",
+        "InstanceID": str(info_data.get("Id")),
+        "JobStartTime": str(info_data.get("StartTime")),
+        "JobStatus": job_state,
+        "JobUntilTime": "NA",
+        "Message": str(info_data.get("Message")),
+        "MessageArguments": message_argument,
+        "MessageID": str(info_data.get("MessageId")),
+        "Name": str(info_data.get("Name")),
+        "PercentComplete": str(info_data.get("PercentComplete")),
+        "Status": job_status,
+        "ActualRunningStopTime": str(info_data.get("ActualRunningStopTime")),
+        "JobType": str(info_data.get("JobType")),
+        "ActualRunningStartTime": str(info_data.get("ActualRunningStartTime")),
+        "EndTime": str(info_data.get("EndTime")),
+        "CompletionTime": str(info_data.get("CompletionTime")),
+        "Description": str(info_data.get("Description")),
+        "TargetSettingsURI": str(info_data.get("TargetSettingsURI"))
+    }
+    transformed_data.append(transformed_info_data)
+
+    return transformed_data
+
+
+def get_lifecycle_controller_job_status_info(idrac, module):
+    try:
+        response = idrac.invoke_request(method='GET', uri=GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10.format(module.params.get('job_id')))
+        if response.status_code == 200:
+            transformed_job_status_data = transform_job_status_data(response.json_data)
+            return transformed_job_status_data
path: plugins/modules/idrac_lifecycle_controller_job_status_info.py
user: login: trisha-dell
body: done

created_at: 2025-04-09T15:31:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -47,32 +63,187 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_redfish_system_info_connection_mock.invoke_request.side_effect = exc_type('https://testhost.com', 404,
+                                                                                        'http error message',
+                                                                                        {"accept-type": "application/json"},
+                                                                                        StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    def test_main_idrac_get_lc_job_status_success_case02(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        # Scenario 1: run and accept_eula both as true
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Completed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": ["NA"],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
+
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        # Scenario 1: run and accept_eula both as true
path: tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
user: login: trisha-dell
body: removed the comment
created_at: 2025-04-09T15:31:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,10 +99,84 @@
 
 import json
 from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10
+from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from ansible.module_utils.basic import AnsibleModule
 
+ERR_STATUS = 404
+
+
+def get_from_wsman(module):
+    with iDRACConnection(module.params) as idrac:
+        job_id, msg = module.params.get('job_id'), {}
+        msg = idrac.job_mgr.get_job_status(job_id)
+        if msg.get('Status') == "Found Fault":
+            module.exit_json(msg="Job ID is invalid.", failed=True)
+    return msg
+
+
+def transform_job_status_data(info_data):
+    transformed_data = []
+
+    job_success_list = ['Completed', 'Success']
+    job_failed_list = ['Failed', 'Errors']
+    job_state = str(info_data.get("JobState"))
+    if job_state in job_success_list:
+        job_status = "Success"
+    elif job_state in job_failed_list:
+        job_status = "Failed"
+    elif 'Message' in info_data and str(info_data.get("Message")) and \
+            'completed' in str(info_data.get("Message")) and \
+            'errors' not in str(info_data.get("Message")):
+        job_status = "Success"
+    else:
+        job_status = "InProgress"
+
+    if len(info_data.get("MessageArgs")) > 0:
+        message_argument = str(info_data.get("MessageArgs")[0])
+    else:
+        message_argument = ""
+
+    transformed_info_data = {
+        "ElapsedTimeSinceCompletion": "",
+        "InstanceID": str(info_data.get("Id")),
+        "JobStartTime": str(info_data.get("StartTime")),
+        "JobStatus": job_state,
+        "JobUntilTime": "NA",
+        "Message": str(info_data.get("Message")),
+        "MessageArguments": message_argument,
+        "MessageID": str(info_data.get("MessageId")),
+        "Name": str(info_data.get("Name")),
+        "PercentComplete": str(info_data.get("PercentComplete")),
+        "Status": job_status,
+        "ActualRunningStopTime": str(info_data.get("ActualRunningStopTime")),
+        "JobType": str(info_data.get("JobType")),
+        "ActualRunningStartTime": str(info_data.get("ActualRunningStartTime")),
+        "EndTime": str(info_data.get("EndTime")),
+        "CompletionTime": str(info_data.get("CompletionTime")),
+        "Description": str(info_data.get("Description")),
+        "TargetSettingsURI": str(info_data.get("TargetSettingsURI"))
+    }
+    transformed_data.append(transformed_info_data)
+
+    return transformed_data
+
+
+def get_lifecycle_controller_job_status_info(idrac, module):
+    try:
+        response = idrac.invoke_request(method='GET', uri=GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10.format(module.params.get('job_id')))
path: plugins/modules/idrac_lifecycle_controller_job_status_info.py
user: login: ABHISHEK-SINHA10
body: @trisha-dell Please take care of this comment.
created_at: 2025-04-10T03:52:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -47,32 +63,183 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_redfish_system_info_connection_mock.invoke_request.side_effect = exc_type('https://testhost.com', 404,
+                                                                                        'http error message',
+                                                                                        {"accept-type": "application/json"},
+                                                                                        StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    def test_main_idrac_get_lc_job_status_success_case02(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Completed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": ["NA"],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
+
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Failed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": [],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
path: tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
user: login: ABHISHEK-SINHA10
body: why only asserting changed value, what about response detail, please assert that too in all UT
created_at: 2025-04-10T03:55:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -47,32 +63,183 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_redfish_system_info_connection_mock.invoke_request.side_effect = exc_type('https://testhost.com', 404,
+                                                                                        'http error message',
+                                                                                        {"accept-type": "application/json"},
+                                                                                        StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    def test_main_idrac_get_lc_job_status_success_case02(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Completed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": ["NA"],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
+
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Failed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": [],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
path: tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
user: login: trisha-dell
body: I have followed the existing UTs. This would require extra effort. I will consider this as a secondary deliverable.
created_at: 2025-04-14T10:51:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -47,32 +63,183 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_redfish_system_info_connection_mock.invoke_request.side_effect = exc_type('https://testhost.com', 404,
+                                                                                        'http error message',
+                                                                                        {"accept-type": "application/json"},
+                                                                                        StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    def test_main_idrac_get_lc_job_status_success_case02(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Completed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": ["NA"],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
+
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Failed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": [],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
path: tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
user: login: ABHISHEK-SINHA10
body: @trisha-dell please take care in this new sprint. otherwise, it'll be tech debt for us which we don't want.
created_at: 2025-04-17T05:09:58Z
author_association: CONTRIBUTOR
path: plugins/module_utils/idrac_utils/info/firmware.py
user: login: ABHISHEK-SINHA10
body: Please add UT of this file. Please have separate UT file for utils, as we don't want to touch module file tomorrow when adding code in utils file and vice-versa.
created_at: 2025-04-18T04:40:56Z
author_association: CONTRIBUTOR
path: plugins/module_utils/idrac_utils/info/lifecycle_controller_job_status.py
user: login: ABHISHEK-SINHA10
body: Please add UT of this file. Please have separate UT file for utils, as we don't want to touch module file tomorrow when adding code in utils file and vice-versa.
created_at: 2025-04-18T04:41:04Z
author_association: CONTRIBUTOR
path: plugins/module_utils/idrac_utils/info/firmware.py
user: login: trisha-dell
body: done
created_at: 2025-04-23T16:45:17Z
author_association: CONTRIBUTOR
path: plugins/module_utils/idrac_utils/info/lifecycle_controller_job_status.py
user: login: trisha-dell
body: done
created_at: 2025-04-23T16:45:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,10 +99,84 @@
 
 import json
 from ansible_collections.dellemc.openmanage.plugins.module_utils.dellemc_idrac import iDRACConnection, idrac_auth_params
+from ansible_collections.dellemc.openmanage.plugins.module_utils.utils import GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10
+from ansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfish import iDRACRedfishAPI
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
 from ansible.module_utils.urls import ConnectionError, SSLValidationError
 from ansible.module_utils.basic import AnsibleModule
 
+ERR_STATUS = 404
+
+
+def get_from_wsman(module):
+    with iDRACConnection(module.params) as idrac:
+        job_id, msg = module.params.get('job_id'), {}
+        msg = idrac.job_mgr.get_job_status(job_id)
+        if msg.get('Status') == "Found Fault":
+            module.exit_json(msg="Job ID is invalid.", failed=True)
+    return msg
+
+
+def transform_job_status_data(info_data):
+    transformed_data = []
+
+    job_success_list = ['Completed', 'Success']
+    job_failed_list = ['Failed', 'Errors']
+    job_state = str(info_data.get("JobState"))
+    if job_state in job_success_list:
+        job_status = "Success"
+    elif job_state in job_failed_list:
+        job_status = "Failed"
+    elif 'Message' in info_data and str(info_data.get("Message")) and \
+            'completed' in str(info_data.get("Message")) and \
+            'errors' not in str(info_data.get("Message")):
+        job_status = "Success"
+    else:
+        job_status = "InProgress"
+
+    if len(info_data.get("MessageArgs")) > 0:
+        message_argument = str(info_data.get("MessageArgs")[0])
+    else:
+        message_argument = ""
+
+    transformed_info_data = {
+        "ElapsedTimeSinceCompletion": "",
+        "InstanceID": str(info_data.get("Id")),
+        "JobStartTime": str(info_data.get("StartTime")),
+        "JobStatus": job_state,
+        "JobUntilTime": "NA",
+        "Message": str(info_data.get("Message")),
+        "MessageArguments": message_argument,
+        "MessageID": str(info_data.get("MessageId")),
+        "Name": str(info_data.get("Name")),
+        "PercentComplete": str(info_data.get("PercentComplete")),
+        "Status": job_status,
+        "ActualRunningStopTime": str(info_data.get("ActualRunningStopTime")),
+        "JobType": str(info_data.get("JobType")),
+        "ActualRunningStartTime": str(info_data.get("ActualRunningStartTime")),
+        "EndTime": str(info_data.get("EndTime")),
+        "CompletionTime": str(info_data.get("CompletionTime")),
+        "Description": str(info_data.get("Description")),
+        "TargetSettingsURI": str(info_data.get("TargetSettingsURI"))
+    }
+    transformed_data.append(transformed_info_data)
+
+    return transformed_data
+
+
+def get_lifecycle_controller_job_status_info(idrac, module):
+    try:
+        response = idrac.invoke_request(method='GET', uri=GET_IDRAC_LIFECYCLE_CONTROLLER_JOB_STATUS_INFO_10.format(module.params.get('job_id')))
path: plugins/modules/idrac_lifecycle_controller_job_status_info.py
user: login: trisha-dell
body: done
created_at: 2025-04-23T16:46:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -47,32 +63,183 @@ def idrac_get_lc_job_status_connection_mock(self, mocker, idrac_mock):
         idrac_conn_class_mock.return_value.__enter__.return_value = idrac_mock
         return idrac_mock
 
+    @pytest.mark.parametrize("exc_type", [HTTPError])
     def test_main_idrac_get_lc_job_status_success_case01(self, idrac_get_lc_job_status_connection_mock,
-                                                         idrac_default_args, mocker):
+                                                         exc_type,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        json_str = to_text(json.dumps({"data": "out"}))
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_redfish_system_info_connection_mock.invoke_request.side_effect = exc_type('https://testhost.com', 404,
+                                                                                        'http error message',
+                                                                                        {"accept-type": "application/json"},
+                                                                                        StringIO(json_str))
         idrac_default_args.update({"job_id": "job_id"})
         idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
         result = self._run_module(idrac_default_args)
         assert result["changed"] is False
 
+    def test_main_idrac_get_lc_job_status_success_case02(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Completed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": ["NA"],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
+
+    def test_main_idrac_get_lc_job_status_success_case03(self, idrac_get_lc_job_status_connection_mock,
+                                                         idrac_redfish_system_info_mock,
+                                                         idrac_redfish_system_info_connection_mock,
+                                                         idrac_default_args,
+                                                         mocker):
+        obj = MagicMock()
+        obj.status_code = 200
+        obj.json_data = {
+            "ActualRunningStartTime": None,
+            "ActualRunningStopTime": None,
+            "CompletionTime": "2025-04-01T11:05:17",
+            "Description": "Job Instance",
+            "EndTime": "TIME_NA",
+            "Id": "JID_435235166998",
+            "JobState": "Failed",
+            "JobType": "iDRACConfiguration",
+            "Message": "Job successfully completed.",
+            "MessageArgs": [],
+            "MessageId": "JCP007",
+            "Name": "Configure: iDRAC.Embedded.1",
+            "PercentComplete": 100,
+            "StartTime": "2025-04-01T11:05:16",
+            "TargetSettingsURI": None,
+            "status_code": 200}
+        mocker.patch(MODULE_PATH + "idrac_lifecycle_controller_job_status_info",
+                     return_value=True)
+        idrac_default_args.update({"job_id": "job_id"})
+        idrac_redfish_system_info_mock.get_entityjson.return_value = None
+        idrac_redfish_system_info_connection_mock.invoke_request.return_value = obj
+        idrac_redfish_system_info_connection_mock.get_json_device.return_value = ""
+        idrac_get_lc_job_status_connection_mock.job_mgr.get_job_status.return_value = {"Status": "Success"}
+        result = self._run_module(idrac_default_args)
+        assert result["changed"] is False
path: tests/unit/plugins/modules/test_idrac_lifecycle_controller_job_status_info.py
user: login: trisha-dell
body: done
created_at: 2025-04-23T16:47:05Z
author_association: CONTRIBUTOR

PR comments:
user: login: ansible-collections-svc
created_at: 2025-04-04T06:00:04Z
body: Can one of the admins verify this patch?
author_association: COLLABORATOR
user: login: trisha-dell
created_at: 2025-04-23T16:45:55Z
body: ![Screenshot 2025-04-23 221105](https://github.com/user-attachments/assets/bddc35b9-8c70-4bc0-b4ab-aa7cb9549b0f)
![Screenshot 2025-04-23 221439](https://github.com/user-attachments/assets/347fa445-f12a-479f-8b81-788c7e4cde8e)

author_association: CONTRIBUTOR
user: login: trisha-dell
created_at: 2025-04-23T16:55:31Z
body: ![Uploading Screenshot 2025-04-23 222502.png…]()

author_association: CONTRIBUTOR