Repository: ansible-collections/community.general

Issue:
Error when installing packages with snap after update to 8.1.0
### Summary

When trying to update install packages via snap module after upgrade to ansible 8.1.0 the task fails. Although they are properly installed.
Rolling back to the previous version (7.x) solves the issue.


### Issue Type

Bug Report

### Component Name

snap

### Ansible Version

```console (paste below)
ansible [core 2.15.1]
  config file = None
  configured module search path = ['/Users/jamicque/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/homebrew/Cellar/ansible/8.1.0/libexec/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/jamicque/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/homebrew/bin/ansible
  python version = 3.11.4 (main, Jun 20 2023, 17:23:00) [Clang 14.0.3 (clang-1403.0.22.14.1)] (/opt/homebrew/Cellar/ansible/8.1.0/libexec/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

```


### Community.general Version

```console (paste below)
empty
```


### Configuration

```console (paste below)
CONFIG_FILE() = None
PAGER(env: PAGER) = less
```


### OS / Environment

Os X 13.4.1 (22F82)

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: install microk8s on the host
  remote_user: root
  hosts: all
  gather_facts: false
  tasks:
  - name: install microk8s & kubectl
    snap:
      name:
        - microk8s
        - kubectl
      classic: yes

```


### Expected Results

installed microk8s and kubectl without errors

### Actual Results

https://gist.github.com/maciejkra/51d283c5b066a231fe38d6ad0aa02407

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/snap.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/snap.py)

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @angristan @vcarceler
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
CC @russoz - could be related to #6468 or #6435.
hi @maciejkra thanks for reporting this issue. I assume the OSX 13.4.1 you reported is the OS on the controller node. Could you please confirm what the OS is on the target node? TIA
Oh sorry it was my mistake.
The target node is Ubuntu 22.04
I ran that same input on my local vagrant setup and could not reproduce the error - microk8s and kubectl were installed without issues. Will have to investigate further.
What I'm seeing so far is:
- the actual snap commands don't seem to be failing
- the snap output in the gist seems to be a lot more verbose than mine, including colors and progress reporting
- the line where the exception is raised is hit when it fails to parse the output of the snap command

So that leads me to believe that the parsing is the problem. I still don't know why the output in my test is more terse than yours. Any thing you could think of?

Anyways, it's late here at GMT+12, I'll resume this tomorrow. 
Hi,
I don’t have any idea, apart from that, that if I downgrade to v.7 it works fine.
So decently some issue is happening only with newer version 
Good morning from the other side.
```
vagrant@ubuntu-jammy:~$ snap version
snap    2.59.5
snapd   2.59.5
series  16
ubuntu  22.04
kernel  5.15.0-75-generic
```
Could you please compare this output with yours and let us know the differences? TIA

In the mean while, I continue to try and find out why snap here produces a different output from snap there.
@maciejkra do you have anything configured in `/etc/snap`? In this local VM I have here, even after installing `snapd` there is no `/etc/snap` at all. Just shaking that tree as well.
Hi, the OS ia am testing this on is a standard VM from Digital Ocean. Sorry I was testing it on 22.10 not 22.04.

Bellow is the configuration output:
```root@ubuntu-s-2vcpu-2gb-amd-fra1-01:~# snap version
snap    2.57.4+22.10ubuntu1
snapd   2.57.4+22.10ubuntu1
series  16
ubuntu  22.10
kernel  5.19.0-23-generic
```

Answering your question no dictionary in /etc/snap
Downgrading ansible, solves the issue.

Hi @maciejkra 

I am tailoring an unit test to reproduce that situation, and based on the outputs provided (thank you!) we have managed to reproduce the error in unit testing.

I still find it odd that we fail to reproduce that in the local VMs though. I have ran it with Ubuntu 22.04 and 22.10, the vagrant images used were:
* ubuntu/jammy64 (Ubuntu 22.04)
* generic/ubuntu2210

In your tests, the output is consistent with the output we get when running `snap` manually in a terminal, with the fancy progress bar and all the terminal sparks and gimmicks associated with that. In my test setup, `snap` seems to be running as if **not** associated with a terminal, and that's what I have experienced whenever I run Ansible for anything. I am wondering what could be set up differently to cause that behaviour. @felixfontein any ideas there? Maybe something in `ansible.cfg` ?

@russoz thank you https://github.com/ansible-collections/community.general/pull/6826 fixes the issue!

Resolving patch:
diff --git a/plugins/modules/snap.py b/plugins/modules/snap.py
--- a/plugins/modules/snap.py
+++ b/plugins/modules/snap.py
@@ -207,25 +207,25 @@ def _run_multiple_commands(self, commands, actionable_names, bundle=True, refres
                 rc, out, err = ctx.run(state=state, name=actionable_names)
                 results_cmd.append(commands + actionable_names)
                 results_rc.append(rc)
-                results_out.append(out)
-                results_err.append(err)
+                results_out.append(out.strip())
+                results_err.append(err.strip())
                 results_run_info.append(ctx.run_info)
             else:
                 for name in actionable_names:
                     rc, out, err = ctx.run(state=state, name=name)
                     results_cmd.append(commands + [name])
                     results_rc.append(rc)
-                    results_out.append(out)
-                    results_err.append(err)
+                    results_out.append(out.strip())
+                    results_err.append(err.strip())
                     results_run_info.append(ctx.run_info)
 
-        return [
+        return (
             '; '.join([to_native(x) for x in results_cmd]),
             self._first_non_zero(results_rc),
             '\n'.join(results_out),
             '\n'.join(results_err),
             results_run_info,
-        ]
+        )
 
     def __quit_module__(self):
         if self.vars.channel is None:
@@ -324,8 +324,8 @@ def _present(self, actionable_snaps, refresh=False):
             self.vars.run_info = run_info
 
         if rc == 0:
-            match_install = [self.__install_re.match(line) for line in out.split('\n')]
-            match_install = [m.group('name') in actionable_snaps for m in match_install if m]
+            match_install2 = [self.__install_re.match(line) for line in out.split('\n')]
+            match_install = [m.group('name') in actionable_snaps for m in match_install2 if m]
             if len(match_install) == len(actionable_snaps):
                 return
 


Test patch:
diff --git a/tests/unit/plugins/modules/test_snap.py b/tests/unit/plugins/modules/test_snap.py
new file mode 100644
--- /dev/null
+++ b/tests/unit/plugins/modules/test_snap.py
@@ -0,0 +1,473 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) Alexei Znamensky (russoz@gmail.com)
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import json
+
+from collections import namedtuple
+from ansible_collections.community.general.plugins.modules import snap
+
+import pytest
+
+TESTED_MODULE = snap.__name__
+
+
+ModuleTestCase = namedtuple("ModuleTestCase", ["id", "input", "output", "run_command_calls"])
+RunCmdCall = namedtuple("RunCmdCall", ["command", "environ", "rc", "out", "err"])
+
+
+@pytest.fixture
+def patch_get_bin_path(mocker):
+    """
+    Function used for mocking AnsibleModule.get_bin_path
+    """
+    def mockie(self, path, *args, **kwargs):
+        return "/testbin/{0}".format(path)
+    mocker.patch("ansible.module_utils.basic.AnsibleModule.get_bin_path", mockie)
+
+
+issue_6803_status_out = """Name    Version      Rev    Tracking         Publisher    Notes
+core20  20220826     1623   latest/stable    canonical**  base
+lxd     5.6-794016a  23680  latest/stable/…  canonical**  -
+snapd   2.57.4       17336  latest/stable    canonical**  snapd
+"""
+
+issue_6803_microk8s_out = (
+    "\rEnsure prerequisites for \"microk8s\" are available                              /"
+    "\rDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"                     "
+    "\rDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"                     \\"
+    "\rDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"                     "
+    "\rDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"                     /\u001b[?25"
+    "\r\u001b[7m\u001b[0mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"     0%     0B/s ages"
+    "\r\u001b[7m\u001b[0mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"     0%     0B/s ages"
+    "\r\u001b[7m\u001b[0mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"     0%     0B/s ages"
+    "\r\u001b[7m\u001b[0mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"     0%  880kB/s 3m21"
+    "\r\u001b[7m\u001b[0mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"     1% 2.82MB/s 1m02"
+    "\r\u001b[7mD\u001b[0mownload snap \"microk8s\" (5372) from channel \"1.27/stable\"     2% 4.71MB/s 37.0"
+    "\r\u001b[7mDo\u001b[0mwnload snap \"microk8s\" (5372) from channel \"1.27/stable\"     4% 9.09MB/s 18.8"
+    "\r\u001b[7mDown\u001b[0mload snap \"microk8s\" (5372) from channel \"1.27/stable\"     6% 12.4MB/s 13.5"
+    "\r\u001b[7mDownl\u001b[0moad snap \"microk8s\" (5372) from channel \"1.27/stable\"     7% 14.5MB/s 11.3"
+    "\r\u001b[7mDownloa\u001b[0md snap \"microk8s\" (5372) from channel \"1.27/stable\"     9% 15.9MB/s 10.1"
+    "\r\u001b[7mDownload \u001b[0msnap \"microk8s\" (5372) from channel \"1.27/stable\"    11% 18.0MB/s 8.75"
+    "\r\u001b[7mDownload s\u001b[0mnap \"microk8s\" (5372) from channel \"1.27/stable\"    13% 19.4MB/s 7.91"
+    "\r\u001b[7mDownload sn\u001b[0map \"microk8s\" (5372) from channel \"1.27/stable\"    15% 20.1MB/s 7.50"
+    "\r\u001b[7mDownload snap\u001b[0m \"microk8s\" (5372) from channel \"1.27/stable\"    17% 20.9MB/s 7.05"
+    "\r\u001b[7mDownload snap \"\u001b[0mmicrok8s\" (5372) from channel \"1.27/stable\"    19% 22.1MB/s 6.50"
+    "\r\u001b[7mDownload snap \"m\u001b[0microk8s\" (5372) from channel \"1.27/stable\"    21% 22.9MB/s 6.11"
+    "\r\u001b[7mDownload snap \"mic\u001b[0mrok8s\" (5372) from channel \"1.27/stable\"    23% 23.2MB/s 5.90"
+    "\r\u001b[7mDownload snap \"micr\u001b[0mok8s\" (5372) from channel \"1.27/stable\"    25% 23.9MB/s 5.58"
+    "\r\u001b[7mDownload snap \"microk\u001b[0m8s\" (5372) from channel \"1.27/stable\"    27% 24.5MB/s 5.30"
+    "\r\u001b[7mDownload snap \"microk8\u001b[0ms\" (5372) from channel \"1.27/stable\"    29% 24.9MB/s 5.09"
+    "\r\u001b[7mDownload snap \"microk8s\"\u001b[0m (5372) from channel \"1.27/stable\"    31% 25.4MB/s 4.85"
+    "\r\u001b[7mDownload snap \"microk8s\" (\u001b[0m5372) from channel \"1.27/stable\"    33% 25.8MB/s 4.63"
+    "\r\u001b[7mDownload snap \"microk8s\" (5\u001b[0m372) from channel \"1.27/stable\"    35% 26.2MB/s 4.42"
+    "\r\u001b[7mDownload snap \"microk8s\" (53\u001b[0m72) from channel \"1.27/stable\"    36% 26.3MB/s 4.30"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372\u001b[0m) from channel \"1.27/stable\"    38% 26.7MB/s 4.10"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) \u001b[0mfrom channel \"1.27/stable\"    40% 26.9MB/s 3.95"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) f\u001b[0mrom channel \"1.27/stable\"    42% 27.2MB/s 3.77"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) fro\u001b[0mm channel \"1.27/stable\"    44% 27.4MB/s 3.63"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from\u001b[0m channel \"1.27/stable\"    46% 27.8MB/s 3.44"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from c\u001b[0mhannel \"1.27/stable\"    48% 27.9MB/s 3.31"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from cha\u001b[0mnnel \"1.27/stable\"    50% 28.1MB/s 3.15"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from chan\u001b[0mnel \"1.27/stable\"    52% 28.3MB/s 3.02"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channe\u001b[0ml \"1.27/stable\"    54% 28.5MB/s 2.87"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel\u001b[0m \"1.27/stable\"    56% 28.6MB/s 2.75"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \u001b[0m\"1.27/stable\"    57% 28.7MB/s 2.63"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1\u001b[0m.27/stable\"    60% 28.9MB/s 2.47"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.2\u001b[0m7/stable\"    62% 29.0MB/s 2.35"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27\u001b[0m/stable\"    63% 29.1MB/s 2.23"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/s\u001b[0mtable\"    65% 29.2MB/s 2.10"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/st\u001b[0mable\"    67% 29.4MB/s 1.97"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stab\u001b[0mle\"    69% 29.5MB/s 1.85"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stabl\u001b[0me\"    71% 29.5MB/s 1.74"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"\u001b[0m    73% 29.7MB/s 1.59"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"  \u001b[0m  75% 29.8MB/s 1.48"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"   \u001b[0m 77% 29.8MB/s 1.37"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    7\u001b[0m9% 29.9MB/s 1.26"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    81\u001b[0m% 30.0MB/s 1.14"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    83% \u001b[0m30.1MB/s 1.01"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    84% 3\u001b[0m0.1MB/s 919m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    86% 30.\u001b[0m1MB/s 810m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    88% 30.2\u001b[0mMB/s 676m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    91% 30.3MB\u001b[0m/s 555m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    93% 30.4MB/s\u001b[0m 436m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    95% 30.5MB/s \u001b[0m317m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    96% 30.5MB/s 21\u001b[0m1m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"    98% 30.5MB/s 117\u001b[0mm"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"   100% 30.5MB/s  11m\u001b[0m"
+    "\r\u001b[7mDownload snap \"microk8s\" (5372) from channel \"1.27/stable\"   100% 30.0MB/s 0.0ns\u001b[0"
+    "\rFetch and check assertions for snap \"microk8s\" (5372)                          "
+    "\rMount snap \"microk8s\" (5372)                                                   \\"
+    "\rMount snap \"microk8s\" (5372)                                                   "
+    "\rMount snap \"microk8s\" (5372)                                                   "
+    "\rMount snap \"microk8s\" (5372)                                                   "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 \\"
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 \\"
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 \\"
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rSetup snap \"microk8s\" (5372) security profiles                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 \\"
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rRun install hook of \"microk8s\" snap if present                                 "
+    "\rStart snap \"microk8s\" (5372) services                                          \\"
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          \\"
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          \\"
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          \\"
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          "
+    "\rStart snap \"microk8s\" (5372) services                                          \\"
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               \\"
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               \\"
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               \\"
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               \\"
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun configure hook of \"microk8s\" snap if present                               \\"
+    "\rRun configure hook of \"microk8s\" snap if present                               "
+    "\rRun service command \"restart\" for services [\"daemon-apiserver-proxy\"] of snap \""
+    "\r\u001b[0m\u001b[?25h\u001b[Kmicrok8s (1.27/stable) v1.27.2 from Canonical** installed\n"
+)
+
+issue_6803_kubectl_out = (
+    "\rEnsure prerequisites for \"kubectl\" are available                              /"
+    "\rDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"                     "
+    "\rDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"                     \\"
+    "\rDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"                     "
+    "\rDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"                     /\u001b[?25"
+    "\r\u001b[7m\u001b[0mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"     0%     0B/s ages"
+    "\r\u001b[7m\u001b[0mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"     0%     0B/s ages"
+    "\r\u001b[7m\u001b[0mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"     0%     0B/s ages"
+    "\r\u001b[7m\u001b[0mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"     0%  880kB/s 3m21"
+    "\r\u001b[7m\u001b[0mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"     1% 2.82MB/s 1m02"
+    "\r\u001b[7mD\u001b[0mownload snap \"kubectl\" (5372) from channel \"1.27/stable\"     2% 4.71MB/s 37.0"
+    "\r\u001b[7mDo\u001b[0mwnload snap \"kubectl\" (5372) from channel \"1.27/stable\"     4% 9.09MB/s 18.8"
+    "\r\u001b[7mDown\u001b[0mload snap \"kubectl\" (5372) from channel \"1.27/stable\"     6% 12.4MB/s 13.5"
+    "\r\u001b[7mDownl\u001b[0moad snap \"kubectl\" (5372) from channel \"1.27/stable\"     7% 14.5MB/s 11.3"
+    "\r\u001b[7mDownloa\u001b[0md snap \"kubectl\" (5372) from channel \"1.27/stable\"     9% 15.9MB/s 10.1"
+    "\r\u001b[7mDownload \u001b[0msnap \"kubectl\" (5372) from channel \"1.27/stable\"    11% 18.0MB/s 8.75"
+    "\r\u001b[7mDownload s\u001b[0mnap \"kubectl\" (5372) from channel \"1.27/stable\"    13% 19.4MB/s 7.91"
+    "\r\u001b[7mDownload sn\u001b[0map \"kubectl\" (5372) from channel \"1.27/stable\"    15% 20.1MB/s 7.50"
+    "\r\u001b[7mDownload snap\u001b[0m \"kubectl\" (5372) from channel \"1.27/stable\"    17% 20.9MB/s 7.05"
+    "\r\u001b[7mDownload snap \"\u001b[0mkubectl\" (5372) from channel \"1.27/stable\"    19% 22.1MB/s 6.50"
+    "\r\u001b[7mDownload snap \"m\u001b[0kubectl\" (5372) from channel \"1.27/stable\"    21% 22.9MB/s 6.11"
+    "\r\u001b[7mDownload snap \"mic\u001b[0mrok8s\" (5372) from channel \"1.27/stable\"    23% 23.2MB/s 5.90"
+    "\r\u001b[7mDownload snap \"micr\u001b[0mok8s\" (5372) from channel \"1.27/stable\"    25% 23.9MB/s 5.58"
+    "\r\u001b[7mDownload snap \"microk\u001b[0m8s\" (5372) from channel \"1.27/stable\"    27% 24.5MB/s 5.30"
+    "\r\u001b[7mDownload snap \"microk8\u001b[0ms\" (5372) from channel \"1.27/stable\"    29% 24.9MB/s 5.09"
+    "\r\u001b[7mDownload snap \"kubectl\"\u001b[0m (5372) from channel \"1.27/stable\"    31% 25.4MB/s 4.85"
+    "\r\u001b[7mDownload snap \"kubectl\" (\u001b[0m5372) from channel \"1.27/stable\"    33% 25.8MB/s 4.63"
+    "\r\u001b[7mDownload snap \"kubectl\" (5\u001b[0m372) from channel \"1.27/stable\"    35% 26.2MB/s 4.42"
+    "\r\u001b[7mDownload snap \"kubectl\" (53\u001b[0m72) from channel \"1.27/stable\"    36% 26.3MB/s 4.30"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372\u001b[0m) from channel \"1.27/stable\"    38% 26.7MB/s 4.10"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) \u001b[0mfrom channel \"1.27/stable\"    40% 26.9MB/s 3.95"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) f\u001b[0mrom channel \"1.27/stable\"    42% 27.2MB/s 3.77"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) fro\u001b[0mm channel \"1.27/stable\"    44% 27.4MB/s 3.63"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from\u001b[0m channel \"1.27/stable\"    46% 27.8MB/s 3.44"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from c\u001b[0mhannel \"1.27/stable\"    48% 27.9MB/s 3.31"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from cha\u001b[0mnnel \"1.27/stable\"    50% 28.1MB/s 3.15"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from chan\u001b[0mnel \"1.27/stable\"    52% 28.3MB/s 3.02"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channe\u001b[0ml \"1.27/stable\"    54% 28.5MB/s 2.87"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel\u001b[0m \"1.27/stable\"    56% 28.6MB/s 2.75"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \u001b[0m\"1.27/stable\"    57% 28.7MB/s 2.63"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1\u001b[0m.27/stable\"    60% 28.9MB/s 2.47"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.2\u001b[0m7/stable\"    62% 29.0MB/s 2.35"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27\u001b[0m/stable\"    63% 29.1MB/s 2.23"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/s\u001b[0mtable\"    65% 29.2MB/s 2.10"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/st\u001b[0mable\"    67% 29.4MB/s 1.97"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stab\u001b[0mle\"    69% 29.5MB/s 1.85"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stabl\u001b[0me\"    71% 29.5MB/s 1.74"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"\u001b[0m    73% 29.7MB/s 1.59"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"  \u001b[0m  75% 29.8MB/s 1.48"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"   \u001b[0m 77% 29.8MB/s 1.37"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    7\u001b[0m9% 29.9MB/s 1.26"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    81\u001b[0m% 30.0MB/s 1.14"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    83% \u001b[0m30.1MB/s 1.01"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    84% 3\u001b[0m0.1MB/s 919m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    86% 30.\u001b[0m1MB/s 810m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    88% 30.2\u001b[0mMB/s 676m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    91% 30.3MB\u001b[0m/s 555m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    93% 30.4MB/s\u001b[0m 436m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    95% 30.5MB/s \u001b[0m317m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    96% 30.5MB/s 21\u001b[0m1m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"    98% 30.5MB/s 117\u001b[0mm"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"   100% 30.5MB/s  11m\u001b[0m"
+    "\r\u001b[7mDownload snap \"kubectl\" (5372) from channel \"1.27/stable\"   100% 30.0MB/s 0.0ns\u001b[0"
+    "\rFetch and check assertions for snap \"kubectl\" (5372)                          "
+    "\rMount snap \"kubectl\" (5372)                                                   \\"
+    "\rMount snap \"kubectl\" (5372)                                                   "
+    "\rMount snap \"kubectl\" (5372)                                                   "
+    "\rMount snap \"kubectl\" (5372)                                                   "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 \\"
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 \\"
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 \\"
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rSetup snap \"kubectl\" (5372) security profiles                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 \\"
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rRun install hook of \"kubectl\" snap if present                                 "
+    "\rStart snap \"kubectl\" (5372) services                                          \\"
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          \\"
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          \\"
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          \\"
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          "
+    "\rStart snap \"kubectl\" (5372) services                                          \\"
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               \\"
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               \\"
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               \\"
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               \\"
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun configure hook of \"kubectl\" snap if present                               \\"
+    "\rRun configure hook of \"kubectl\" snap if present                               "
+    "\rRun service command \"restart\" for services [\"daemon-apiserver-proxy\"] of snap \""
+    "\r\u001b[0m\u001b[?25h\u001b[Kkubectl (1.27/stable) v1.27.2 from Canonical** installed\n"
+)
+
+TEST_CASES = [
+    ModuleTestCase(
+        id="issue_6803",
+        input={"name": ["microk8s", "kubectl"], "classic": True},
+        output=dict(changed=True, snaps_installed=["microk8s", "kubectl"]),
+        run_command_calls=[
+            RunCmdCall(
+                command=['/testbin/snap', 'list'],
+                environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
+                rc=0,
+                out=issue_6803_status_out,
+                err="",
+            ),
+            RunCmdCall(
+                command=['/testbin/snap', 'install', '--classic', 'microk8s'],
+                environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
+                rc=0,
+                out=issue_6803_microk8s_out,
+                err="",
+            ),
+            RunCmdCall(
+                command=['/testbin/snap', 'install', '--classic', 'kubectl'],
+                environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
+                rc=0,
+                out=issue_6803_kubectl_out,
+                err="",
+            ),
+        ]
+    ),
+]
+TEST_CASES_IDS = [item.id for item in TEST_CASES]
+
+
+@pytest.mark.parametrize("patch_ansible_module, testcase",
+                         [[x.input, x] for x in TEST_CASES],
+                         ids=TEST_CASES_IDS,
+                         indirect=["patch_ansible_module"])
+@pytest.mark.usefixtures("patch_ansible_module")
+def test_snap(mocker, capfd, patch_get_bin_path, testcase):
+    """
+    Run unit tests for test cases listen in TEST_CASES
+    """
+
+    run_cmd_calls = testcase.run_command_calls
+
+    # Mock function used for running commands first
+    call_results = [(x.rc, x.out, x.err) for x in run_cmd_calls]
+    mock_run_command = mocker.patch(
+        "ansible.module_utils.basic.AnsibleModule.run_command",
+        side_effect=call_results)
+
+    # Try to run test case
+    with pytest.raises(SystemExit):
+        snap.main()
+
+    out, err = capfd.readouterr()
+    results = json.loads(out)
+    print("testcase =\n%s" % str(testcase))
+    print("results =\n%s" % results)
+
+    assert mock_run_command.call_count == len(run_cmd_calls)
+    if mock_run_command.call_count:
+        call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list]
+        expected_call_args_list = [(item.command, item.environ) for item in run_cmd_calls]
+        print("call args list =\n%s" % call_args_list)
+        print("expected args list =\n%s" % expected_call_args_list)
+        try:
+            assert call_args_list == expected_call_args_list
+        except AssertionError:
+            for test_call_run, expected_call_run in zip(call_args_list, expected_call_args_list):
+                assert test_call_run == expected_call_run
+
+    assert results.get("changed", False) == testcase.output["changed"]
+    if "failed" in testcase:
+        assert results.get("failed", False) == testcase.output["failed"]
+    if "msg" in testcase:
+        assert results.get("msg", "") == testcase.output["msg"]