nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: containers/podman
Pull request #17272 (2023-01-30 07:33:40)

[v4.4] Match VT device paths to be blocked from mounting exactly
This is an automated cherry-pick of #17265

/assign vrothberg

```release-note
None
```


Patch:
diff --git a/pkg/util/utils_linux.go b/pkg/util/utils_linux.go
index e1e87c6d6d..468524405d 100644
--- a/pkg/util/utils_linux.go
+++ b/pkg/util/utils_linux.go
@@ -5,8 +5,9 @@ import (
 	"fmt"
 	"io/fs"
 	"os"
-	"path"
 	"path/filepath"
+	"strconv"
+	"strings"
 	"syscall"
 
 	"github.com/containers/podman/v4/libpod/define"
@@ -70,20 +71,23 @@ func FindDeviceNodes() (map[string]string, error) {
 	return nodes, nil
 }
 
-func isVirtualConsoleDevice(device string) bool {
+// isVirtualConsoleDevice returns true if path is a virtual console device
+// (/dev/tty\d+).
+// The passed path must be clean (filepath.Clean).
+func isVirtualConsoleDevice(path string) bool {
 	/*
 		Virtual consoles are of the form `/dev/tty\d+`, any other device such as
 		/dev/tty, ttyUSB0, or ttyACM0 should not be matched.
 		See `man 4 console` for more information.
-
-		NOTE: Matching is done using path.Match even though a regular expression
-		      would have been more accurate. This is because a regular
-			  expression would have required pre-compilation, which would have
-			  increase the startup time needlessly or made the code more complex
-			  than needed.
 	*/
-	matched, _ := path.Match("/dev/tty[0-9]*", device)
-	return matched
+	suffix := strings.TrimPrefix(path, "/dev/tty")
+	if suffix == path || suffix == "" {
+		return false
+	}
+
+	// 16bit because, max. supported TTY devices is 512 in Linux 6.1.5.
+	_, err := strconv.ParseUint(suffix, 10, 16)
+	return err == nil
 }
 
 func AddPrivilegedDevices(g *generate.Generator, systemdMode bool) error {


Test patch:
diff --git a/pkg/util/utils_linux_test.go b/pkg/util/utils_linux_test.go
new file mode 100644
index 0000000000..9d75a20c8f
--- /dev/null
+++ b/pkg/util/utils_linux_test.go
@@ -0,0 +1,54 @@
+package util
+
+import (
+	"testing"
+)
+
+func TestIsVirtualConsoleDevice(t *testing.T) {
+	testcases := []struct {
+		expectedResult bool
+		path           string
+	}{
+		{
+			expectedResult: true,
+			path:           "/dev/tty10",
+		},
+		{
+			expectedResult: false,
+			path:           "/dev/tty",
+		},
+		{
+			expectedResult: false,
+			path:           "/dev/ttyUSB0",
+		},
+		{
+			expectedResult: false,
+			path:           "/dev/tty0abcd",
+		},
+		{
+			expectedResult: false,
+			path:           "1234",
+		},
+		{
+			expectedResult: false,
+			path:           "abc",
+		},
+		{
+			expectedResult: false,
+			path:           " ",
+		},
+		{
+			expectedResult: false,
+			path:           "",
+		},
+	}
+
+	for _, tc := range testcases {
+		t.Run(tc.path, func(t *testing.T) {
+			result := isVirtualConsoleDevice(tc.path)
+			if result != tc.expectedResult {
+				t.Errorf("isVirtualConsoleDevice returned %t, expected %t", result, tc.expectedResult)
+			}
+		})
+	}
+}
Repository: m3db/m3db-operator
Pull request #316 (2022-03-15 08:16:56)

prevent scaling down to 0 instances
After discussing with Linas we agreed that scaling to 0 does not really makes sense and probably won't work. Since placement needs to be discarded.


Patch:
diff --git a/pkg/controller/update_cluster.go b/pkg/controller/update_cluster.go
index 142af92..5192aee 100644
--- a/pkg/controller/update_cluster.go
+++ b/pkg/controller/update_cluster.go
@@ -590,8 +590,8 @@ func (c *M3DBController) findPodsAndInstancesToRemove(
 	if len(pods) == 0 {
 		return nil, nil, errEmptyPodList
 	}
-	if desiredInstanceCount < 0 {
-		msg := fmt.Sprintf("desired instance count is negative: %d", desiredInstanceCount)
+	if desiredInstanceCount <= 0 {
+		msg := fmt.Sprintf("desired instance count should be positive, but is: %d", desiredInstanceCount)
 		return nil, nil, pkgerrors.New(msg)
 	}
 


Test patch:
diff --git a/pkg/controller/update_cluster_test.go b/pkg/controller/update_cluster_test.go
index b1840dd..a320548 100644
--- a/pkg/controller/update_cluster_test.go
+++ b/pkg/controller/update_cluster_test.go
@@ -715,20 +715,16 @@ func TestShrinkPlacementForSet(t *testing.T) {
 			expectedRemovedIds:     []string{`{"name":"cluster-zones-rep0-1","uid":"1"}`},
 		},
 		{
-			name:                   "remove more pods than exists",
+			name:                   "negative desired instance count",
 			desiredInstanceCount:   -42,
 			placementInstanceCount: instanceCountPerGroup,
-			expectedErr:            "desired instance count is negative: -42",
+			expectedErr:            "desired instance count should be positive, but is: -42",
 		},
 		{
-			name:                   "remove all pods",
+			name:                   "0 desired instances",
 			desiredInstanceCount:   0,
 			placementInstanceCount: instanceCountPerGroup,
-			expectedRemovedIds: []string{
-				`{"name":"cluster-zones-rep0-2","uid":"2"}`,
-				`{"name":"cluster-zones-rep0-1","uid":"1"}`,
-				`{"name":"cluster-zones-rep0-0","uid":"0"}`,
-			},
+			expectedErr:            "desired instance count should be positive, but is: 0",
 		},
 		{
 			name:               "prevent scale down",
Repository: kubernetes-sigs/gcp-filestore-csi-driver
Pull request #326 (2022-07-18 20:32:06)

include REPAIRING as valid non-ready state
**What type of PR is this?**
/kind bug


**What this PR does / why we need it**:
Filestore instances can get into `REPAIRING` state and per Filestore team's recommendation we should block on it and wait for the state to go back to `READY`

**Which issue(s) this PR fixes**:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
[b/239199315](http://b/239199315)

**Special notes for your reviewer**:

**Does this PR introduce a user-facing change?**:
<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
-->
```release-note
NONE
```



Patch:
diff --git a/pkg/csi_driver/multishare_ops_manager.go b/pkg/csi_driver/multishare_ops_manager.go
index 8ac864f9..bd07ddcf 100644
--- a/pkg/csi_driver/multishare_ops_manager.go
+++ b/pkg/csi_driver/multishare_ops_manager.go
@@ -327,7 +327,7 @@ func (m *MultishareOpsManager) runEligibleInstanceCheck(ctx context.Context, ins
 	nonReadyInstanceCount := 0
 
 	for _, instance := range instances {
-		if instance.State == "CREATING" {
+		if instance.State == "CREATING" || instance.State == "REPAIRING" {
 			klog.Infof("Instance %s/%s/%s with state %s is not ready", instance.Project, instance.Location, instance.Name, instance.State)
 			nonReadyInstanceCount += 1
 			continue


Test patch:
diff --git a/pkg/csi_driver/multishare_ops_manager_test.go b/pkg/csi_driver/multishare_ops_manager_test.go
index 1ebea604..7965bee8 100644
--- a/pkg/csi_driver/multishare_ops_manager_test.go
+++ b/pkg/csi_driver/multishare_ops_manager_test.go
@@ -1575,6 +1575,24 @@ func TestRunEligibleInstanceCheck(t *testing.T) {
 					},
 					State: "READY",
 				},
+				{
+					Name:     "instance-5",
+					Location: "us-central1",
+					Project:  "test-project",
+					Labels: map[string]string{
+						util.ParamMultishareInstanceScLabelKey: "testprefix",
+					},
+					State: "ERROR",
+				},
+				{
+					Name:     "instance-6",
+					Location: "us-central1",
+					Project:  "test-project",
+					Labels: map[string]string{
+						util.ParamMultishareInstanceScLabelKey: "testprefix",
+					},
+					State: "SUSPENDED",
+				},
 			},
 			expectedReadyInstance: []*file.MultishareInstance{
 				{
@@ -1587,7 +1605,7 @@ func TestRunEligibleInstanceCheck(t *testing.T) {
 					State: "READY",
 				},
 			},
-			expectedNonReadyCount: 2,
+			expectedNonReadyCount: 3,
 			ops: []*OpInfo{
 				{
 					Id:     "op1",
Repository: getsentry/responses
Pull request #269 (2019-05-31 03:06:52)

Return quoted value consistently
This PR normalizes the return value of `_cookies_from_headers()` so that the function consistently returns URL-quoted version of non-ASCII characters set as cookie values.

The issue is that when a cookie value involves non-ASCII chars being URL-quoted, `cookies.Cookies.from_request()` appears to return unquoted chars whereas `http.cookies.SimpleCookie.load` does not. This inconsistency makes it tedious to write tests on cookies with non-ASCII characters.


Patch:
diff --git a/responses.py b/responses.py
index 9de9368..9c57301 100644
--- a/responses.py
+++ b/responses.py
@@ -104,6 +104,12 @@ def _is_redirect(response):
         )
 
 
+def _ensure_str(s):
+    if six.PY2:
+        s = s.encode("utf-8") if isinstance(s, six.text_type) else s
+    return s
+
+
 def _cookies_from_headers(headers):
     try:
         import http.cookies as cookies
@@ -115,8 +121,10 @@ def _cookies_from_headers(headers):
     except ImportError:
         from cookies import Cookies
 
-        resp_cookies = Cookies.from_request(headers["set-cookie"])
-        cookies_dict = {v.name: v.value for _, v in resp_cookies.items()}
+        resp_cookies = Cookies.from_request(_ensure_str(headers["set-cookie"]))
+        cookies_dict = {
+            v.name: quote(_ensure_str(v.value)) for _, v in resp_cookies.items()
+        }
     return cookiejar_from_dict(cookies_dict)
 
 


Test patch:
diff --git a/test_responses.py b/test_responses.py
index 0350e49..4740dfb 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -922,3 +922,18 @@ def test_custom_target(monkeypatch):
     requests_mock.start()
     assert len(patch_mock.call_args_list) == 1
     assert patch_mock.call_args[1]["target"] == "something.else"
+
+
+def _quote(s):
+    return responses.quote(responses._ensure_str(s))
+
+
+def test_cookies_from_headers():
+    text = "こんにちは/世界"
+    quoted_text = _quote(text)
+    expected = {"x": "a", "y": quoted_text}
+    headers = {"set-cookie": "; ".join(k + "=" + v for k, v in expected.items())}
+    cookiejar = responses._cookies_from_headers(headers)
+    for k, v in cookiejar.items():
+        assert isinstance(v, str)
+        assert v == expected[k]
Repository: getsentry/responses
Pull request #308 (2020-02-25 15:36:35)

fix: Fix content-type in callbacks using list headers
Fix the content type header in list based callback headers.

Refs #306


Patch:
diff --git a/responses.py b/responses.py
index e841af9..eff4033 100644
--- a/responses.py
+++ b/responses.py
@@ -408,7 +408,14 @@ class CallbackResponse(BaseResponse):
         # If the callback set a content-type remove the one
         # set in add_callback() so that we don't have multiple
         # content type values.
-        if "Content-Type" in r_headers:
+        has_content_type = False
+        if isinstance(r_headers, dict) and "Content-Type" in r_headers:
+            has_content_type = True
+        elif isinstance(r_headers, list):
+            has_content_type = any(
+                [h for h in r_headers if h and h[0].lower() == "content-type"]
+            )
+        if has_content_type:
             headers.pop("Content-Type", None)
 
         body = _handle_body(body)


Test patch:
diff --git a/test_responses.py b/test_responses.py
index f572025..6f6482f 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -499,6 +499,44 @@ def test_callback_no_content_type():
     assert_reset()
 
 
+def test_callback_content_type_dict():
+    def request_callback(request):
+        return (
+            200,
+            {"Content-Type": "application/json"},
+            b"foo",
+        )
+
+    @responses.activate
+    def run():
+        responses.add_callback("GET", "http://mockhost/.foo", callback=request_callback)
+        resp = requests.get("http://mockhost/.foo")
+        assert resp.text == "foo"
+        assert resp.headers["content-type"] == "application/json"
+
+    run()
+    assert_reset()
+
+
+def test_callback_content_type_tuple():
+    def request_callback(request):
+        return (
+            200,
+            [("Content-Type", "application/json")],
+            b"foo",
+        )
+
+    @responses.activate
+    def run():
+        responses.add_callback("GET", "http://mockhost/.foo", callback=request_callback)
+        resp = requests.get("http://mockhost/.foo")
+        assert resp.text == "foo"
+        assert resp.headers["content-type"] == "application/json"
+
+    run()
+    assert_reset()
+
+
 def test_regular_expression_url():
     @responses.activate
     def run():
Repository: getsentry/responses
Pull request #316 (2020-04-07 16:20:39)

Fix bug in handling unicode body
Added a test to return a unicode body and noticed this wasn't working as
the charset wasn't being set. This also highlighted that Response
converts unicode to bytes twice, once in the constructor and once in the
call to _handle_body(), so the conversion in the constructor has been
removed.

There's possibly a similar bug in CallbackResponse too.


Patch:
diff --git a/responses.py b/responses.py
index 96c827d..8545293 100644
--- a/responses.py
+++ b/responses.py
@@ -345,11 +345,10 @@ class Response(BaseResponse):
                 content_type = "application/json"
 
         if content_type is UNSET:
-            content_type = "text/plain"
-
-        # body must be bytes
-        if isinstance(body, six.text_type):
-            body = body.encode("utf-8")
+            if isinstance(body, six.text_type) and _has_unicode(body):
+                content_type = "text/plain; charset=utf-8"
+            else:
+                content_type = "text/plain"
 
         self.body = body
         self.status = status


Test patch:
diff --git a/test_responses.py b/test_responses.py
index d91b54d..9413a5e 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -924,6 +924,21 @@ def test_handles_unicode_url():
     assert_reset()
 
 
+def test_handles_unicode_body():
+    url = "http://example.com/test"
+
+    @responses.activate
+    def run():
+        responses.add(responses.GET, url, body="михољско лето")
+
+        resp = requests.get(url)
+
+        assert_response(resp, "михољско лето", content_type="text/plain; charset=utf-8")
+
+    run()
+    assert_reset()
+
+
 def test_handles_buffered_reader_body():
     url = "http://example.com/test"
Repository: getsentry/responses
Pull request #317 (2020-04-10 16:29:24)

Fix params parsing
Using a simple replace when parsing the params results in an error when there's some path present.
For example, without this fix the new test would break with something like:
```python
AssertionError:
    {'/some/path?hello': 'world', 'example': 'params'}
    {'example': 'params', 'hello': 'world'}
```


Patch:
diff --git a/responses.py b/responses.py
index 8545293..d0d24b6 100644
--- a/responses.py
+++ b/responses.py
@@ -622,7 +622,7 @@ class RequestsMock(object):
     def _on_request(self, adapter, request, **kwargs):
         match = self._find_match(request)
         resp_callback = self.response_callback
-        request.params = dict(parse_qsl(request.path_url.replace("/?", "")))
+        request.params = dict(parse_qsl(urlparse(request.path_url).query))
 
         if match is None:
             if any(


Test patch:
diff --git a/test_responses.py b/test_responses.py
index 9413a5e..6f0162e 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -1122,21 +1122,29 @@ def test_cookies_from_headers():
         assert v == expected[k]
 
 
-def test_request_param():
+@pytest.mark.parametrize(
+    "url",
+    (
+        "http://example.com",
+        "http://example.com/some/path",
+        "http://example.com/other/path/",
+    ),
+)
+def test_request_param(url):
     @responses.activate
     def run():
         params = {"hello": "world", "example": "params"}
         responses.add(
             method=responses.GET,
-            url="http://example.com?hello=world",
+            url="{0}?hello=world".format(url),
             body="test",
             match_querystring=False,
         )
-        resp = requests.get("http://example.com", params=params)
+        resp = requests.get(url, params=params)
         assert_response(resp, "test")
         assert resp.request.params == params
 
-        resp = requests.get("http://example.com")
+        resp = requests.get(url)
         assert_response(resp, "test")
         assert resp.request.params == {}
Repository: getsentry/responses
Pull request #347 (2020-09-09 13:05:09)

Allow matching on empty request body
If there was no body sent in the original request it comes into the matcher as `None`.

phillipuniverse: Took a few tries for a passing build but this should be good to review now!

Patch:
diff --git a/responses.py b/responses.py
index 4a97b2c..3bef0b7 100644
--- a/responses.py
+++ b/responses.py
@@ -236,7 +236,11 @@ _unspecified = object()
 
 def urlencoded_params_matcher(params):
     def match(request_body):
-        return sorted(params.items()) == sorted(parse_qsl(request_body))
+        return (
+            params is None
+            if request_body is None
+            else sorted(params.items()) == sorted(parse_qsl(request_body))
+        )
 
     return match
 
@@ -246,7 +250,11 @@ def json_params_matcher(params):
         try:
             if isinstance(request_body, bytes):
                 request_body = request_body.decode("utf-8")
-            return params == json_module.loads(request_body)
+            return (
+                params is None
+                if request_body is None
+                else params == json_module.loads(request_body)
+            )
         except JSONDecodeError:
             return False
 


Test patch:
diff --git a/test_responses.py b/test_responses.py
index e2d3f48..262f6bb 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -1228,3 +1228,34 @@ def test_request_matches_post_params():
 
     run()
     assert_reset()
+
+
+def test_request_matches_empty_body():
+    @responses.activate
+    def run():
+        responses.add(
+            method=responses.POST,
+            url="http://example.com/",
+            body="one",
+            match=[responses.json_params_matcher(None)],
+        )
+
+        responses.add(
+            method=responses.POST,
+            url="http://example.com/",
+            body="two",
+            match=[responses.urlencoded_params_matcher(None)],
+        )
+
+        resp = requests.request("POST", "http://example.com/")
+        assert_response(resp, "one")
+
+        resp = requests.request(
+            "POST",
+            "http://example.com/",
+            headers={"Content-Type": "x-www-form-urlencoded"},
+        )
+        assert_response(resp, "two")
+
+    run()
+    assert_reset()
Repository: getsentry/responses
Pull request #350 (2020-10-10 08:26:33)

Allow request.params to have multiple values for the same key
After incorporating https://github.com/getsentry/responses/pull/301, responses can return requested parameters by `responses.calls[].request.params`, but it doesn't support multiple values for the same parameter for now.

Although there is no standard about the multiple values for the same request parameter, requests can accept list as value of `params` (ref. [Passing Parameters In URLs](https://requests.readthedocs.io/en/master/user/quickstart/#passing-parameters-in-urls)), so I feel it is better to handle it in the same way.



Patch:
diff --git a/responses.py b/responses.py
index 3bef0b7..6f427b8 100644
--- a/responses.py
+++ b/responses.py
@@ -5,6 +5,8 @@ import inspect
 import json as json_module
 import logging
 import re
+from itertools import groupby
+
 import six
 
 from collections import namedtuple
@@ -662,10 +664,19 @@ class RequestsMock(object):
 
         return found_match
 
+    def _parse_request_params(self, url):
+        params = {}
+        for k, v in groupby(parse_qsl(urlparse(url).query), lambda kv: kv[0]):
+            vs = list(map(lambda x: x[1], v))
+            if len(vs) == 1:
+                vs = vs[0]
+            params[k] = vs
+        return params
+
     def _on_request(self, adapter, request, **kwargs):
         match = self._find_match(request)
         resp_callback = self.response_callback
-        request.params = dict(parse_qsl(urlparse(request.path_url).query))
+        request.params = self._parse_request_params(request.path_url)
 
         if match is None:
             if any(


Test patch:
diff --git a/test_responses.py b/test_responses.py
index 262f6bb..2140f52 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -1152,6 +1152,22 @@ def test_request_param(url):
     assert_reset()
 
 
+def test_request_param_with_multiple_values_for_the_same_key():
+    @responses.activate
+    def run():
+        url = "http://example.com"
+        params = {"key1": ["one", "two"], "key2": "three"}
+        responses.add(
+            method=responses.GET, url=url, body="test",
+        )
+        resp = requests.get(url, params=params)
+        assert_response(resp, "test")
+        assert resp.request.params == params
+
+    run()
+    assert_reset()
+
+
 @pytest.mark.parametrize(
     "url", ("http://example.com", "http://example.com?hello=world")
 )
Repository: getsentry/responses
Pull request #712 (2024-05-03 13:07:55)

fix mocked HEAD response when content-length header is present
This PR is a fix for this issue https://github.com/getsentry/responses/issues/708.
Basically when mocking a response to a HEAD request (which contains a content-length header), we do not pass the request_method. Which results in wrongfully raising a `ChunkedEncodingError`


Patch:
diff --git a/responses/__init__.py b/responses/__init__.py
index d990091..39db1e7 100644
--- a/responses/__init__.py
+++ b/responses/__init__.py
@@ -532,6 +532,7 @@ def _form_response(
     body: Union[BufferedReader, BytesIO],
     headers: Optional[Mapping[str, str]],
     status: int,
+    request_method: Optional[str],
 ) -> HTTPResponse:
     """
     Function to generate `urllib3.response.HTTPResponse` object.
@@ -566,6 +567,7 @@ def _form_response(
         headers=headers,
         original_response=orig_response,  # type: ignore[arg-type]  # See comment above
         preload_content=False,
+        request_method=request_method,
     )
 
 
@@ -632,7 +634,7 @@ class Response(BaseResponse):
             content_length = len(body.getvalue())
             headers["Content-Length"] = str(content_length)
 
-        return _form_response(body, headers, status)
+        return _form_response(body, headers, status, request.method)
 
     def __repr__(self) -> str:
         return (
@@ -695,7 +697,7 @@ class CallbackResponse(BaseResponse):
         body = _handle_body(body)
         headers.extend(r_headers)
 
-        return _form_response(body, headers, status)
+        return _form_response(body, headers, status, request.method)
 
 
 class PassthroughResponse(BaseResponse):


Test patch:
diff --git a/responses/tests/test_responses.py b/responses/tests/test_responses.py
index 12176b9..9088ff3 100644
--- a/responses/tests/test_responses.py
+++ b/responses/tests/test_responses.py
@@ -2416,6 +2416,18 @@ class TestShortcuts:
         run()
         assert_reset()
 
+    def test_head_with_content_length(self):
+        @responses.activate
+        def run():
+            headers = {"content-length": "1000"}
+            responses.head("http://example.com/1", status=200, headers=headers)
+            resp = requests.head("http://example.com/1")
+            assert resp.status_code == 200
+            assert resp.headers["Content-Length"] == "1000"
+
+        run()
+        assert_reset()
+
     def test_options(self):
         @responses.activate
         def run():