internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: ansible/ansible

Issue:
Task retries has no default
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

https://github.com/ansible/ansible/blob/devel/lib/ansible/playbook/task.py#L86
##### ANSIBLE VERSION

```
ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

None
##### OS / ENVIRONMENT

N/A
##### SUMMARY

When trying to run a task as a Do-Until loop, ansible errors out if you don't specify a "retries" value. Per the documentation at http://docs.ansible.com/ansible/playbooks_loops.html#do-until-loops, this should be 3.
##### STEPS TO REPRODUCE

Define a task with and "until" condition and no "retries" condition.
##### EXPECTED RESULTS

"retries" should default to 3.
##### ACTUAL RESULTS

```
TASK [Configure Gluster volumes.] **********************************************
task path: /home/jrivera/projects/github/storhaug/vagrant-ansible/playbooks/storhaug.yml:126
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/ansible/executor/task_executor.py", line 96, in run
    item_results = self._run_loop(items)
  File "/usr/lib/python2.7/site-packages/ansible/executor/task_executor.py", line 252, in _run_loop
    res = self._execute(variables=task_vars)
  File "/usr/lib/python2.7/site-packages/ansible/executor/task_executor.py", line 427, in _execute
    retries = self._task.retries + 1
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

fatal: [ganesh]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py
--- a/lib/ansible/playbook/task.py
+++ b/lib/ansible/playbook/task.py
@@ -81,7 +81,7 @@ class Task(Base, Conditional, Taggable, Become):
     _notify = FieldAttribute(isa='list')
     _poll = FieldAttribute(isa='int', default=10)
     _register = FieldAttribute(isa='string')
-    _retries = FieldAttribute(isa='int')
+    _retries = FieldAttribute(isa='int', default=3)
     _until = FieldAttribute(isa='list', default=[])
 
     def __init__(self, block=None, role=None, task_include=None):


Test patch:
Repository: ansible/ansible

Issue:
lookup properties
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
ansible 2.2.0 (devel 4e369a31db) last updated 2016/07/02 15:01:01 (GMT +400)
  lib/ansible/modules/core: (detached HEAD 1d0d5db97a) last updated 2016/07/02 15:01:12 (GMT +400)
  lib/ansible/modules/extras: (detached HEAD 00b8b96906) last updated 2016/07/02 15:01:12 (GMT +400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
##### CONFIGURATION
##### OS / ENVIRONMENT

"N/A"
##### SUMMARY

[commit](https://github.com/ansible/ansible/commit/4ba60d00c8d7e62912a37ec24f90f6e5d0770c4d)
this commit breaks `lookup` for `type=properties`
##### STEPS TO REPRODUCE

just try to read some properties through `lookup`

```
- name: lookup
  vars:
    property_value: "{{ lookup('ini', 'some.java.property    type=properties   file=config.properties') }}"
  debug: msg="{{ property_value }}"
```
##### EXPECTED RESULTS

read correct value from property file
##### ACTUAL RESULTS

```
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ConfigParser.py", line 512, in _read
    raise MissingSectionHeaderError(fpname, lineno, line)
MissingSectionHeaderError: File contains no section headers.
file: /config.properties, line: 3
'environment=dev\n'

fatal: [localhost]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}

NO MORE HOSTS LEFT *************************************************************
    to retry, use: --limit @test.retry

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1
```

By the way, it would be great to implement 'autofill' properties

```
host=127.0.0.1
api.host=${host}
```

cc @jctanner 



Discussion:

Resolving patch:
diff --git a/lib/ansible/plugins/lookup/ini.py b/lib/ansible/plugins/lookup/ini.py
--- a/lib/ansible/plugins/lookup/ini.py
+++ b/lib/ansible/plugins/lookup/ini.py
@@ -36,7 +36,7 @@
 def _parse_params(term):
     '''Safely split parameter term to preserve spaces'''
 
-    keys = ['key', 'section', 'file', 're']
+    keys = ['key', 'type', 'section', 'file', 're']
     params = {}
     for k in keys:
         params[k] = ''


Test patch:
Repository: ansible/ansible

Issue:
module_utils/netcli.py wait_for match bug
<!---
Please do not report issues/requests related to Ansible modules here !!

Report them to the appropriate modules-core or modules-extras project:
  - https://github.com/ansible/ansible-modules-core/issues
  - https://github.com/ansible/ansible-modules-extras/issues

Also verify first that your issue/request is not already reported in GitHub
-->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### COMPONENT NAME

<!--- Name of the plugin/task/feature -->

lib/ansible/module_utils/netcli.py
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
ansible 2.2.0 (devel f57f33a8e7) last updated 2016/08/26 06:24:44 (GMT +000)
  lib/ansible/modules/core: (detached HEAD ef84dbbddd) last updated 2016/08/26 06:24:55 (GMT +000)
  lib/ansible/modules/extras: (detached HEAD f29efb5626) last updated 2016/08/26 06:24:58 (GMT +000)
```
##### CONFIGURATION

<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
##### OS / ENVIRONMENT

<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->

N/A
##### SUMMARY

<!--- Explain the problem briefly -->

There is a bug in matches function of Conditional class.
##### STEPS TO REPRODUCE

<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->

```
When using wait_for with matches like below:
        ios_command:
          commands:
          - show xxx
          provider: "{{ cli }}"
          retries: 15
          interval: 60
          wait_for:
            - "result[0] matches 'STANDBY RPSW READY\\?\\s*:\\s*YES'"
we expect use the regex to match the output of the command.

In the code, 
    def matches(self, value):
        match = re.search(value, self.value, re.M)
        return match is not None
I think value is the output where self.value is the regex. So the correct code is
    def matches(self, value):
        match = re.search(self.value, value, re.M)
        return match is not None
```

<!--- You can also paste gist.github.com links for larger files -->
##### EXPECTED RESULTS

<!--- What did you expect to happen when running the steps above? -->
##### ACTUAL RESULTS

<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->

```

```



Discussion:

Resolving patch:
diff --git a/lib/ansible/module_utils/netcli.py b/lib/ansible/module_utils/netcli.py
--- a/lib/ansible/module_utils/netcli.py
+++ b/lib/ansible/module_utils/netcli.py
@@ -296,5 +296,5 @@ def contains(self, value):
         return str(self.value) in value
 
     def matches(self, value):
-        match = re.search(value, self.value, re.M)
+        match = re.search(self.value, value, re.M)
         return match is not None


Test patch:
Repository: ansible/ansible

Issue:
Using an empty inventory group no longer noops and instead results in error.
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

ansible
##### ANSIBLE VERSION

Old "good/desired" behavior observed with ansible 2.0.0.2 as installed via `pip install ansible==2.0.0.2`.

New "bad/undesired" behavior observed with ansible 2.1.1.0 as installed via `pip install ansible==2.1.1.0`.
##### CONFIGURATION

No changes made.
##### OS / ENVIRONMENT

Ubuntu Xenial 16.04
##### SUMMARY

If you run ansible against an empty inventory group this now results in an error and failure. Old behavior was to noop and do nothing.
##### STEPS TO REPRODUCE

```
# Install ansible 2.1.1.0
virtualenv /tmp/ansible
# note the paramiko version is fixed to avoid needing system packages.
/tmp/ansible/bin/pip install paramiko==1.16.0 ansible==2.1.1.0
export ANSIBLE=/tmp/ansible/bin/ansible
echo "[primary]" > /tmp/inventory
echo "localhost ansible_connection=local host_counter=1" >> /tmp/inventory
echo "[subnodes]" >> /tmp/inventory
$ANSIBLE subnodes -f 5 -i "/tmp/inventory" -m copy -a "src='/tmp/inventory' dest='/tmp/foo'"
```
##### EXPECTED RESULTS

I expect to continue to have ansible noop on empty groups.
##### ACTUAL RESULTS

`ERROR! Specified hosts and/or --limit does not match any hosts`



Discussion:
this is not an issue of an empty group, but of an empty host list for the play,this was always a failure. The only difference that I see is that it shows 'error' instead of warning:

in 2.0

```
[WARNING]: provided hosts list is empty, only localhost is available
```

in 2.1/2.2

```
ERROR! Specified hosts and/or --limit does not match any hosts
```

I would argue it wasn't a failure before. The exit code was zero. Warning in that case seems reasonable to me in case its not what someone wanted. However changing it to an error breaks backward compatibility with the behavior that was there before. The difference between warning, return 0 and error return non zero is pretty significant.

Not sure what assertions ansible makes about its warnings as far as if and when they may become errors.


Resolving patch:
diff --git a/lib/ansible/cli/adhoc.py b/lib/ansible/cli/adhoc.py
--- a/lib/ansible/cli/adhoc.py
+++ b/lib/ansible/cli/adhoc.py
@@ -139,9 +139,12 @@ def run(self):
 
         inventory.subset(self.options.subset)
         hosts = inventory.list_hosts(pattern)
-        if len(hosts) == 0 and no_hosts is False:
-            # Invalid limit
-            raise AnsibleError("Specified hosts and/or --limit does not match any hosts")
+        if len(hosts) == 0:
+            if no_hosts is False and self.options.subset:
+                # Invalid limit
+                raise AnsibleError("Specified --limit does not match any hosts")
+            else:
+                display.warning("No hosts matched, nothing to do")
 
         if self.options.listhosts:
             display.display('  hosts (%d):' % len(hosts))


Test patch:
Repository: ansible/ansible

Issue:
Ansible throws an exception if inventory file path contains non-ascii characters
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

core
##### ANSIBLE VERSION

`ansible 2.1.2.0`
##### CONFIGURATION

default
##### OS / ENVIRONMENT

Ubuntu 16.04
Python 2.7.12
##### SUMMARY

Ansible fails to load inventory file if path contains non-ascii characters and throws an exception.
Affects `ansible` and `ansible-playbook` commands.
##### STEPS TO REPRODUCE

Create an ansible project and put in a folder containing non-unicode characters (e.g. cyrillic).
Run ansible.

```
ansible -i test -m setup all -vvvv
```
##### EXPECTED RESULTS

Command runs without an error.
##### ACTUAL RESULTS

```
$ ansible -i test -m setup all -vvvv
Using /home/dromanov/Документы/ansible/ansible.cfg as config file
ERROR! Unexpected Exception: 'ascii' codec can't decode byte 0xd0 in position 15: ordinal not in range(128)
the full traceback was:

Traceback (most recent call last):
  File "/usr/bin/ansible", line 92, in <module>
    exit_code = cli.run()
  File "/usr/lib/python2.7/dist-packages/ansible/cli/adhoc.py", line 129, in run
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=self.options.inventory)
  File "/usr/lib/python2.7/dist-packages/ansible/inventory/__init__.py", line 75, in __init__
    self._group_vars_files = self._find_group_vars_files(self._basedir)
  File "/usr/lib/python2.7/dist-packages/ansible/inventory/__init__.py", line 764, in _find_group_vars_files
    found_vars = set(os.listdir(unicode(path)))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 15: ordinal not in range(128)

```



Discussion:
@dmromanov Please try ansible 2.2 rc1 or the devel version and report back whether those still show the issue. There were recent fixes regarding unicode handling and especially the line that produced your issue.


Resolving patch:
diff --git a/lib/ansible/inventory/dir.py b/lib/ansible/inventory/dir.py
--- a/lib/ansible/inventory/dir.py
+++ b/lib/ansible/inventory/dir.py
@@ -70,7 +70,7 @@ def get_file_parser(hostsfile, groups, loader):
             parser = InventoryYAMLParser(loader=loader, groups=groups, filename=hostsfile)
             processed = True
         except Exception as e:
-            myerr.append('Attempted to read "%s" as YAML: %s' % (hostsfile, to_native(e)))
+            myerr.append('Attempted to read "%s" as YAML: %s' % (to_native(hostsfile), to_native(e)))
 
     # ini
     if not processed and not shebang_present:
@@ -78,7 +78,7 @@ def get_file_parser(hostsfile, groups, loader):
             parser = InventoryINIParser(loader=loader, groups=groups, filename=hostsfile)
             processed = True
         except Exception as e:
-            myerr.append('Attempted to read "%s" as ini file: %s ' % (hostsfile, to_native(e)))
+            myerr.append('Attempted to read "%s" as ini file: %s ' % (to_native(hostsfile), to_native(e)))
 
     if not processed and myerr:
         raise AnsibleError('\n'.join(myerr))


Test patch:
Repository: ansible/ansible

Issue:
Async error with check_mode
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

async
##### ANSIBLE VERSION

```
ansible 2.3.0 (detached HEAD 871d3d8945) last updated 2016/10/19 21:49:14 (GMT +200)
  lib/ansible/modules/core: (detached HEAD 6145e24ed4) last updated 2016/10/19 21:49:14 (GMT +200)
  lib/ansible/modules/extras: (detached HEAD accb04b867) last updated 2016/10/19 21:49:14 (GMT +200)
  config file =
  configured module search path = Default w/o overrides
```

```
ansible 2.2.0.0 (detached HEAD 257182e46a) last updated 2016/10/19 21:52:09 (GMT +200)
  lib/ansible/modules/core: (detached HEAD 730f26d52f) last updated 2016/10/19 21:52:09 (GMT +200)
  lib/ansible/modules/extras: (detached HEAD d51b3d5887) last updated 2016/10/19 21:52:10 (GMT +200)
  config file =
  configured module search path = Default w/o overrides
```

```
ansible 2.1.3.0 (detached HEAD e00dc01803) last updated 2016/10/19 21:52:30 (GMT +200)
  lib/ansible/modules/core: (detached HEAD c00ae0082f) last updated 2016/10/19 21:52:31 (GMT +200)
  lib/ansible/modules/extras: (detached HEAD edf10d911e) last updated 2016/10/19 21:52:31 (GMT +200)
  config file =
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

None
##### OS / ENVIRONMENT

OSX, Debian 7, Debian 8
##### SUMMARY
##### STEPS TO REPRODUCE

```
ansible-playbook -i hosts test_async.yml -C

---
# test_async.yml
- hosts: localhost
  gather_facts: no
  tasks:
    - name: async tasks
      command: echo
      async: 10
      poll: 1
```
##### ACTUAL RESULTS

```
PLAY [localhost] ***************************************************************

TASK [async tasks] *************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "No job id was returned by the async task"}
    to retry, use: --limit @/test_async.retry

PLAY RECAP *********************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1

```



Discussion:

Resolving patch:
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
--- a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -501,7 +501,7 @@ def _execute(self, variables=None):
                 vars_copy[self._task.register] = wrap_var(result.copy())
 
             if self._task.async > 0:
-                if self._task.poll > 0:
+                if self._task.poll > 0 and not result.get('skipped'):
                     result = self._poll_async_result(result=result, templar=templar, task_vars=vars_copy)
 
                 # ensure no log is preserved


Test patch:
Repository: ansible/ansible

Issue:
safe_eval() warning for variables containing curly braces and Jinja2 expressions
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

`template/safe_eval`
##### ANSIBLE VERSION

```
ansible 2.2.0.0
  config file = 
  configured module search path = Default w/o overrides
```
##### SUMMARY

There is a strange `safe_eval()` warning if one wants to template a string containing Jinja2 expressions and curly braces. Even escaping the curly braces like `{{ '{}' }}` does not help.
##### STEPS TO REPRODUCE

```
- hosts: localhost
  vars:
    foo: "bar"
  tasks:
    - debug: msg="{}/{{ foo }}"
```
##### EXPECTED RESULTS

Apart from the warning the expected results coincide with the actual ones.
##### ACTUAL RESULTS

```
PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
 [WARNING]: Exception in safe_eval() on expr: {}/bar (name 'bar' is not defined)

ok: [localhost] => {
    "msg": "{}/bar"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/template/safe_eval.py b/lib/ansible/template/safe_eval.py
--- a/lib/ansible/template/safe_eval.py
+++ b/lib/ansible/template/safe_eval.py
@@ -26,12 +26,6 @@
 from ansible import constants as C
 from ansible.plugins import filter_loader, test_loader
 
-try:
-    from __main__ import display
-except ImportError:
-    from ansible.utils.display import Display
-    display = Display()
-
 def safe_eval(expr, locals={}, include_exceptions=False):
     '''
     This is intended for allowing things like:
@@ -143,7 +137,6 @@ def generic_visit(self, node, inside_call=False):
             return (expr, None)
         return expr
     except Exception as e:
-        display.warning('Exception in safe_eval() on expr: %s (%s)' % (expr, e))
         if include_exceptions:
             return (expr, e)
         return expr


Test patch:
Repository: ansible/ansible

Issue:
serial with % groups task per host
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### COMPONENT NAME

serial
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
devel 
ansible 2.2.0.0 (detached HEAD eafb4043c9) last updated 2016/10/25 13:47:30 (GMT +200)
```
##### CONFIGURATION

n/a
##### OS / ENVIRONMENT

n/a
##### SUMMARY

When using serial with `%`, there is a suspicious grouping per host for every task, while I don't see such a grouping when using serial with a number:
##### STEPS TO REPRODUCE

See gist https://gist.github.com/resmo/c650dc1846c14cdccbc41d509c92f4c0

<!--- You can also paste gist.github.com links for larger files -->
##### EXPECTED RESULTS

<!--- What did you expect to happen when running the steps above? -->

```
TASK [command] *****************************************************************
changed: [three] => (item=1)
changed: [one] => (item=1)
changed: [two] => (item=1)
changed: [three] => (item=1)
changed: [one] => (item=1)
changed: [two] => (item=1)
changed: [three] => (item=1)
changed: [one] => (item=1)
changed: [two] => (item=1)
changed: [three] => (item=1)
changed: [one] => (item=1)
changed: [two] => (item=1)

```
##### ACTUAL RESULTS

<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->

```
TASK [command] *****************************************************************
changed: [two] => (item=1)
changed: [two] => (item=1)
changed: [two] => (item=1)
changed: [two] => (item=1)
changed: [one] => (item=1)
changed: [one] => (item=1)
changed: [one] => (item=1)
changed: [one] => (item=1)
changed: [three] => (item=1)
changed: [three] => (item=1)
changed: [three] => (item=1)
changed: [three] => (item=1)
```



Discussion:
I identified 159aa26b36a6455ebc38d527c294c60899892c04 as source

It seems that only one fork is used if serial is e.g. 50% and that is why the tasks look grouped.

My analysis, in https://github.com/ansible/ansible/blob/devel/lib/ansible/executor/task_queue_manager.py#L234 max_serial is 1 because the calculation is (50/100) \* 3 = 1.5 = 1

`num_hosts` here https://github.com/ansible/ansible/blob/devel/lib/ansible/executor/task_queue_manager.py#L225 is 3 (while the total of hosts is 6) so it seems the calculation of 50% has already been done and it will be applied twice. 0.5 \* 6 = 3 \* 0.5 = 1.5 = int 1


Resolving patch:
diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py
--- a/lib/ansible/executor/task_queue_manager.py
+++ b/lib/ansible/executor/task_queue_manager.py
@@ -222,7 +222,7 @@ def run(self, play):
         )
 
         # Fork # of forks, # of hosts or serial, whichever is lowest
-        num_hosts = len(self._inventory.get_hosts(new_play.hosts))
+        num_hosts = len(self._inventory.get_hosts(new_play.hosts, ignore_restrictions=True))
 
         max_serial = 0
         if new_play.serial:


Test patch:
Repository: ansible/ansible

Issue:
Feature Idea: Run syntax/file/role/etc checks before asking for passwords/user inupt
For example, if I'm running a play than needs the --ask-sudo-pass flag, then ansible should not ask for the password until after it's checked for syntax errors, that all the roles exist, and other pre-task checks.



Discussion:
:+1: 

This is a very good idea. It's _very_ frustrating to have to type a long password to then have ansible tell you the playbook cannot be found since your path was wrong.


Resolving patch:
diff --git a/lib/ansible/cli/playbook.py b/lib/ansible/cli/playbook.py
--- a/lib/ansible/cli/playbook.py
+++ b/lib/ansible/cli/playbook.py
@@ -95,6 +95,14 @@ def run(self):
         vault_pass = None
         passwords = {}
 
+        # initial error check, to make sure all specified playbooks are accessible
+        # before we start running anything through the playbook executor
+        for playbook in self.args:
+            if not os.path.exists(playbook):
+                raise AnsibleError("the playbook: %s could not be found" % playbook)
+            if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)):
+                raise AnsibleError("the playbook: %s does not appear to be a file" % playbook)
+
         # don't deal with privilege escalation or passwords when we don't need to
         if not self.options.listhosts and not self.options.listtasks and not self.options.listtags and not self.options.syntax:
             self.normalize_become_options()
@@ -111,14 +119,6 @@ def run(self):
             vault_pass = self.ask_vault_passwords()[0]
             loader.set_vault_password(vault_pass)
 
-        # initial error check, to make sure all specified playbooks are accessible
-        # before we start running anything through the playbook executor
-        for playbook in self.args:
-            if not os.path.exists(playbook):
-                raise AnsibleError("the playbook: %s could not be found" % playbook)
-            if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)):
-                raise AnsibleError("the playbook: %s does not appear to be a file" % playbook)
-
         # create the variable manager, which will be shared throughout
         # the code, ensuring a consistent view of global variables
         variable_manager = VariableManager()


Test patch: