nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: commanded/commanded
Pull request #213 (2018-10-25 15:17:46)

Adding recorded_event to predicate_fn in wait_for_event
Adding second optional parameter to the predicate_fn which now receive the recorded_event as second param, containing all the informations about the event.


## Why

I needed to be sure that an event was produce before another one, and I needed to check some metadata too.

```elixir
wait_for_event(
  MoneyDeposited,
  fn event, recorded_event ->
    event.amount == 50 and recorded_event.event_number == 2
  end
)
```


Signed-off-by: Freyskeyd <simon.paitrault@gmail.com>


Patch:
diff --git a/lib/commanded/assertions/event_assertions.ex b/lib/commanded/assertions/event_assertions.ex
index 94c9269..abd5019 100644
--- a/lib/commanded/assertions/event_assertions.ex
+++ b/lib/commanded/assertions/event_assertions.ex
@@ -162,7 +162,8 @@ defmodule Commanded.Assertions.EventAssertions do
     expected_event =
       Enum.find(received_events, fn received_event ->
         case received_event.event_type do
-          ^expected_type -> apply(predicate_fn, [received_event.data])
+          ^expected_type when is_function(predicate_fn, 2) -> apply(predicate_fn, [received_event.data, received_event])
+          ^expected_type when is_function(predicate_fn, 1) -> apply(predicate_fn, [received_event.data])
           _ -> false
         end
       end)


Test patch:
diff --git a/test/event/handle_event_test.exs b/test/event/handle_event_test.exs
index dd325bd..f449e13 100644
--- a/test/event/handle_event_test.exs
+++ b/test/event/handle_event_test.exs
@@ -93,7 +93,7 @@ defmodule Commanded.Event.HandleEventTest do
 
       :ok = EventStore.append_to_stream(stream_uuid, 1, to_event_data(new_events))
 
-      wait_for_event(MoneyDeposited)
+      wait_for_event(MoneyDeposited, fn event, recorded_event -> event.amount == 50 and recorded_event.event_number == 2 end)
 
       Wait.until(fn ->
         assert AppendingEventHandler.received_events() == new_events
Repository: commanded/commanded
Pull request #432 (2021-02-04 13:19:20)

Make sure the metadata must be map type.
When a non-map type metadata is entered, Raise an exception.


Patch:
diff --git a/lib/commanded/commands/router.ex b/lib/commanded/commands/router.ex
index a39fc96..b7dac6f 100644
--- a/lib/commanded/commands/router.ex
+++ b/lib/commanded/commands/router.ex
@@ -519,7 +519,8 @@ defmodule Commanded.Commands.Router do
           command_uuid = Keyword.get(opts, :command_uuid, UUID.uuid4())
           consistency = Keyword.fetch!(opts, :consistency)
           correlation_id = Keyword.get(opts, :correlation_id, UUID.uuid4())
-          metadata = Keyword.fetch!(opts, :metadata)
+          metadata = opts |> Keyword.fetch!(:metadata) |> validate_metadata()
+
           retry_attempts = Keyword.get(opts, :retry_attempts)
           timeout = Keyword.fetch!(opts, :timeout)
 
@@ -588,6 +589,10 @@ defmodule Commanded.Commands.Router do
 
         {:error, :unregistered_command}
       end
+
+      # Make sure the metadata must be Map.t()
+      defp validate_metadata(value) when is_map(value), do: value
+      defp validate_metadata(_), do: raise(ArgumentError, message: "metadata must be an map")
     end
   end
 


Test patch:
diff --git a/test/commands/routing_commands_test.exs b/test/commands/routing_commands_test.exs
index 9bb0320..928ce51 100644
--- a/test/commands/routing_commands_test.exs
+++ b/test/commands/routing_commands_test.exs
@@ -322,4 +322,16 @@ defmodule Commanded.Commands.RoutingCommandsTest do
       assert event.metadata == metadata
     end)
   end
+
+  test "make sure metadata must be map" do
+    metadata = [ip_address: "127.0.0.1"]
+
+    assert_raise ArgumentError, "metadata must be an map", fn ->
+      MultiCommandHandlerRouter.dispatch(
+        %OpenAccount{account_number: "ACC123", initial_balance: 1_000},
+        application: DefaultApp,
+        metadata: metadata
+      )
+    end
+  end
 end
Repository: commanded/commanded
Pull request #463 (2021-11-22 19:40:31)

Event Handler not calling init on restart
Hello!

I've experience the following issues that I don't think its the intended behaviour.

Im using and Event Handler state for saving dynamic information and restoring on the `init/1` callback.
Last week a EH crashed to my surprise the EH process, the new one that the supervisor started, did not run the `init/1`
The reason for this is that `init/1` was called once in the `child_spec` definition and it was not calling the module start link.
So what end up happening is that the init/1 is called only once at the first start of the Event Handler

With this change the only downside that im seeing is that `parse_config!` is called in the `child_spec` and also in the `start_link`

I haven't found a way to get around that, because in the `init/1` callback you can define the application and the name, so calling it in the child_spec is needed in the same way is needed to be called in the `start_link/1`






Patch:
diff --git a/lib/commanded/event/handler.ex b/lib/commanded/event/handler.ex
index f4cba9b..840c661 100644
--- a/lib/commanded/event/handler.ex
+++ b/lib/commanded/event/handler.ex
@@ -517,11 +517,9 @@ defmodule Commanded.Event.Handler do
       def child_spec(opts) do
         opts = Keyword.merge(@opts, opts)
 
-        {application, name, config} = Handler.parse_config!(__MODULE__, opts)
-
         default = %{
-          id: {__MODULE__, application, name},
-          start: {Handler, :start_link, [application, name, __MODULE__, config]},
+          id: {__MODULE__, opts},
+          start: {__MODULE__, :start_link, [opts]},
           restart: :permanent,
           type: :worker
         }


Test patch:
diff --git a/test/event/event_handler_state_test.exs b/test/event/event_handler_state_test.exs
index a543da7..6a0cdb8 100644
--- a/test/event/event_handler_state_test.exs
+++ b/test/event/event_handler_state_test.exs
@@ -77,7 +77,7 @@ defmodule Commanded.Event.EventHandlerStateTest do
       assert_receive {:event, ^event1, metadata}
       assert match?(%{state: 11}, metadata)
 
-      %{id: id} = StatefulEventHandler.child_spec([])
+      %{id: id} = StatefulEventHandler.child_spec(state: 10)
 
       stop_supervised!(id)
 
diff --git a/test/event/handler_init_test.exs b/test/event/handler_init_test.exs
index f11976e..0b16ce0 100644
--- a/test/event/handler_init_test.exs
+++ b/test/event/handler_init_test.exs
@@ -34,6 +34,16 @@ defmodule Commanded.Event.HandlerInitTest do
       assert_handler_name(handler2, "Commanded.Event.RuntimeConfigHandler.tenant2")
       assert_handler_name(handler3, "Commanded.Event.RuntimeConfigHandler.tenant3")
     end
+
+    test "should be called on restart if the process crashes" do
+      handler = start_supervised!({RuntimeConfigHandler, tenant: :tenant1, reply_to: self()})
+
+      Process.exit(handler, :kill)
+
+      assert_receive {:init, :tenant1}
+      assert_receive {:init, :tenant1}
+      refute_receive {:init, :tenant1}
+    end
   end
 
   describe "event handler `init/0` callback" do
Repository: commanded/commanded
Pull request #464 (2021-12-03 14:53:46)

Call process manager `init/1` function on process restart
Ensure the `init/1` callback function is called whenever a process manager restarts.


Patch:
diff --git a/lib/commanded/process_managers/process_manager.ex b/lib/commanded/process_managers/process_manager.ex
index c4d5486..f0991f2 100644
--- a/lib/commanded/process_managers/process_manager.ex
+++ b/lib/commanded/process_managers/process_manager.ex
@@ -455,13 +455,9 @@ defmodule Commanded.ProcessManagers.ProcessManager do
 
       """
       def child_spec(opts) do
-        opts = Keyword.merge(@opts, opts)
-
-        {application, name, config} = ProcessManager.parse_config!(__MODULE__, opts)
-
         default = %{
-          id: {__MODULE__, application, name},
-          start: {ProcessRouter, :start_link, [application, name, __MODULE__, config]},
+          id: {__MODULE__, opts},
+          start: {__MODULE__, :start_link, [opts]},
           restart: :permanent,
           type: :worker
         }


Test patch:
diff --git a/test/process_managers/process_manager_init_test.exs b/test/process_managers/process_manager_init_test.exs
index 8a5f508..b096c11 100644
--- a/test/process_managers/process_manager_init_test.exs
+++ b/test/process_managers/process_manager_init_test.exs
@@ -22,5 +22,15 @@ defmodule Commanded.ProcessManager.ProcessManagerInitTest do
       assert_receive {:init, :tenant2}
       assert_receive {:init, :tenant3}
     end
+
+    test "should be called on restart if the process crashes" do
+      pm = start_supervised!({RuntimeConfigProcessManager, tenant: :tenant1, reply_to: self()})
+
+      Process.exit(pm, :kill)
+
+      assert_receive {:init, :tenant1}
+      assert_receive {:init, :tenant1}
+      refute_receive {:init, :tenant1}
+    end
   end
 end
Repository: commanded/commanded
Pull request #489 (2022-07-27 07:27:38)

Support and test for OTP 25


Patch:
diff --git a/.tool-versions b/.tool-versions
index 245d8dc..6d5c811 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,2 +1,2 @@
-elixir 1.13.4-otp-24
-erlang 24.3.4
+elixir 1.13.4-otp-25
+erlang 25.0.3
diff --git a/lib/commanded/aggregates/aggregate.ex b/lib/commanded/aggregates/aggregate.ex
index f7fc124..0e95634 100644
--- a/lib/commanded/aggregates/aggregate.ex
+++ b/lib/commanded/aggregates/aggregate.ex
@@ -377,7 +377,7 @@ defmodule Commanded.Aggregates.Aggregate do
   @doc false
   @impl GenServer
   def handle_info({:events, events}, %Aggregate{} = state) do
-    %Aggregate{application: application, lifespan_timeout: lifespan_timeout} = state
+    %Aggregate{application: application} = state
 
     Logger.debug(fn -> describe(state) <> " received events: #{inspect(events)}" end)
 
@@ -389,7 +389,7 @@ defmodule Commanded.Aggregates.Aggregate do
 
       state = Enum.reduce(events, state, &handle_event/2)
 
-      {:noreply, state, lifespan_timeout}
+      {:noreply, state}
     catch
       {:error, error} ->
         Logger.debug(fn -> describe(state) <> " stopping due to: #{inspect(error)}" end)


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c83aa28..f8a543e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -8,7 +8,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        otp: ['23.3', '24.3']
+        otp: ['23.3.4', '24.3.4', '25.0.3']
         elixir: ['1.13.4']
 
     steps:
Repository: commanded/commanded
Pull request #512 (2022-11-23 20:23:15)

Properly handle EXIT signal in event handler


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f650456..6c303cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@
 
 -  Record aggregate state while processing `Commanded.Aggregate.Multi` ([#507](https://github.com/commanded/commanded/pull/507)).
 
+- Properly handle EXIT signal in event handler ([#512](https://github.com/commanded/commanded/pull/512)).
+
 ## v1.4.1
 
 ### Enhancements
diff --git a/lib/commanded/event/handler.ex b/lib/commanded/event/handler.ex
index f4852a5..ed36322 100644
--- a/lib/commanded/event/handler.ex
+++ b/lib/commanded/event/handler.ex
@@ -820,6 +820,18 @@ defmodule Commanded.Event.Handler do
     {:stop, reason, state}
   end
 
+  @doc false
+  @impl GenServer
+  def handle_info({:EXIT, _pid, :normal}, state) do
+    # linked process exited normally, don't shutdown
+    {:noreply, state}
+  end
+
+  @impl GenServer
+  def handle_info({:EXIT, _pid, reason}, state) do
+    {:stop, reason, state}
+  end
+
   @doc false
   @impl GenServer
   def handle_info(message, state) do


Test patch:
diff --git a/test/event/handle_event_test.exs b/test/event/handle_event_test.exs
index 0da0eb5..4b1828b 100644
--- a/test/event/handle_event_test.exs
+++ b/test/event/handle_event_test.exs
@@ -85,6 +85,25 @@ defmodule Commanded.Event.HandleEventTest do
       refute_receive {:event, _handler, _event, _metadata}
     end
 
+    test "should handle exit signals", %{handler: handler} do
+      import ExUnit.CaptureLog
+
+      ref = Process.monitor(handler)
+
+      spawn(fn ->
+        Process.exit(handler, :shutdown)
+      end)
+
+      send_unexpected_mesage = fn ->
+        send(handler, :unexpected_message)
+        assert_receive {:DOWN, ^ref, :process, ^handler, :shutdown}
+      end
+
+      log = capture_log(send_unexpected_mesage)
+      refute log =~ "received unexpected message"
+      refute log =~ ":EXIT"
+    end
+
     test "should ignore unexpected messages", %{handler: handler} do
       import ExUnit.CaptureLog
Repository: commanded/commanded
Pull request #563 (2024-07-12 12:23:12)

fix(router.ex): Telemetry is not emitted if dispatch fails for {:error, :unregistered_command}
#475 @davydog187 


Patch:
diff --git a/lib/commanded/commands/router.ex b/lib/commanded/commands/router.ex
index 6059930..5ba9bc1 100644
--- a/lib/commanded/commands/router.ex
+++ b/lib/commanded/commands/router.ex
@@ -209,6 +209,7 @@ defmodule Commanded.Commands.Router do
   alias Commanded.Aggregates.DefaultLifespan
   alias Commanded.Commands.{ExecutionResult, Router}
   alias Commanded.UUID
+  alias Commanded.Telemetry
 
   defmacro __using__(opts) do
     quote do
@@ -578,11 +579,32 @@ defmodule Commanded.Commands.Router do
       end
 
       # Catch unregistered commands, log and return an error.
-      defp do_dispatch(command, _opts) do
+      defp do_dispatch(command, opts) do
+        event_prefix = [:commanded, :application, :dispatch]
+        application = Keyword.fetch!(opts, :application)
+
+        context = %Commanded.Aggregates.ExecutionContext{
+          command: command
+        }
+
+        telemetry_metadata = %{
+          application: application,
+          error: nil,
+          execution_context: context
+        }
+
+        start_time = Telemetry.start(event_prefix, telemetry_metadata)
+
         Logger.error(fn ->
           "attempted to dispatch an unregistered command: " <> inspect(command)
         end)
 
+        Telemetry.stop(
+          event_prefix,
+          start_time,
+          Map.put(telemetry_metadata, :error, :unregistered_command)
+        )
+
         {:error, :unregistered_command}
       end
 


Test patch:
diff --git a/test/application/telemetry_test.exs b/test/application/telemetry_test.exs
index fba16ae..a6f563c 100644
--- a/test/application/telemetry_test.exs
+++ b/test/application/telemetry_test.exs
@@ -4,6 +4,7 @@ defmodule Commanded.Application.TelemetryTest do
   alias Commanded.DefaultApp
   alias Commanded.Middleware.Commands.IncrementCount
   alias Commanded.Middleware.Commands.RaiseError
+  alias Commanded.Middleware.Commands.Fail
   alias Commanded.UUID
 
   setup do
@@ -58,6 +59,20 @@ defmodule Commanded.Application.TelemetryTest do
              meta
   end
 
+  test "emit `[:commanded, :application, :dispatch, :start | :stop]` event on unregistered command" do
+    command = %Fail{aggregate_uuid: UUID.uuid4()}
+    error = :unregistered_command
+
+    assert {:error, ^error} = TestRouter.dispatch(command, application: DefaultApp)
+
+    assert_receive {[:commanded, :application, :dispatch, :start], 1, _meas, _meta}
+
+    assert_receive {[:commanded, :application, :dispatch, :stop], 2, _meas, meta}
+
+    assert %{application: DefaultApp, error: ^error, execution_context: %{command: ^command}} =
+             meta
+  end
+
   defp attach_telemetry do
     agent = start_supervised!({Agent, fn -> 1 end})
Repository: coryodaniel/bonny
Pull request #207 (2023-04-09 17:48:19)

Leader Election: Add missing permission to access leases
In order for the leader election to work, the operator needs access to resources of type `coordination.k8s.io/leases`.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7be349a..5640953 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 <!-- ### Added | Changed | Deprecated | Removed | Fixed | Security -->
 
+## [1.1.3] - 2023-04-09
+
+- Leader Election: Add missing RBAC permission to access leases - [#207](https://github.com/coryodaniel/bonny/pull/207)
+
 ## [1.1.2] - 2023-03-07
 
 ### Added
diff --git a/lib/mix/operator.ex b/lib/mix/operator.ex
index 2621837..cb54c30 100644
--- a/lib/mix/operator.ex
+++ b/lib/mix/operator.ex
@@ -32,6 +32,11 @@ defmodule Bonny.Mix.Operator do
         apiGroups: ["events.k8s.io"],
         resources: ["events"],
         verbs: ["*"]
+      },
+      %{
+        apiGroups: ["coordination.k8s.io"],
+        resources: ["leases"],
+        verbs: ["*"]
       }
     ]
   end


Test patch:
diff --git a/test/mix/operator_test.exs b/test/mix/operator_test.exs
index 4f4a87f..f779dc2 100644
--- a/test/mix/operator_test.exs
+++ b/test/mix/operator_test.exs
@@ -17,6 +17,7 @@ defmodule Bonny.Mix.OperatorTest do
           verbs: ["*"]
         },
         %{apiGroups: ["events.k8s.io"], resources: ["events"], verbs: ["*"]},
+        %{apiGroups: ["coordination.k8s.io"], resources: ["leases"], verbs: ["*"]},
         %{apiGroups: ["example.com"], resources: ["widgets"], verbs: ["*"]},
         %{apiGroups: ["example.com"], resources: ["cogs"], verbs: ["*"]},
         %{apiGroups: ["example.com"], resources: ["whizbangs"], verbs: ["*"]},
Repository: auth0/auth0-python
Pull request #66 (2017-06-07 17:00:06)

Updated Rules.all to exclude enabled parameter if enabled=None
I found a bug in the Rules.all method that causes limited behavior in the Python API compared to what is allowed by the REST API.  The REST API specified the boolean parameter `enabled`, which if `true` will result in only rules that are enabled being returned by the API.  If `false`, only rules that are disabled will be returned by the API.  If this parameter is not provided, then all rules will be returned regardless of whether they are enabled or disabled.

The Python API only supports providing `True` or `False` for the `enabled` parameter in the Rules.all function, which results in the enabled parameter always being included in the request to the REST API.  This means that one cannot request all rules regardless of enabled or disabled in a single request.

I've updated the Rules.all function to accept `None` as a value for the `enabled` parameter.  If `None` is provided, the `enabled` parameter will not be included in the request at all and the response will contain all rules regardless of whether they are enabled or deleted.  If a value other than `None` is provided, then the function behaves as it did before this change.


Patch:
diff --git a/auth0/v3/management/rules.py b/auth0/v3/management/rules.py
index c346bfc..a6e8d7c 100644
--- a/auth0/v3/management/rules.py
+++ b/auth0/v3/management/rules.py
@@ -46,9 +46,11 @@ class Rules(object):
 
         params = {'fields': ','.join(fields) or None,
                   'include_fields': str(include_fields).lower(),
-                  'enabled': str(enabled).lower(),
                   'stage': stage}
 
+        if enabled != None:
+            params['enabled'] = str(enabled).lower()
+
         return self.client.get(self._url(), params=params)
 
     def create(self, body):


Test patch:
diff --git a/auth0/v3/test/management/test_rules.py b/auth0/v3/test/management/test_rules.py
index 59741f1..e4cc339 100644
--- a/auth0/v3/test/management/test_rules.py
+++ b/auth0/v3/test/management/test_rules.py
@@ -31,6 +31,16 @@ class TestRules(unittest.TestCase):
                                             'enabled': 'false',
                                             'stage': 'stage'})
 
+        c.all(stage='stage', enabled=None, fields=['a', 'b'],
+              include_fields=False)
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/rules', args[0])
+        self.assertEqual(kwargs['params'], {'fields': 'a,b',
+                                            'include_fields': 'false',
+                                            'stage': 'stage'})
+
     @mock.patch('auth0.v3.management.rules.RestClient')
     def test_create(self, mock_rc):
         mock_instance = mock_rc.return_value
Repository: auth0/auth0-python
Pull request #77 (2017-09-18 16:21:43)

Added upsert parameter to import users job
The Auth0 Management API supports an `upsert` boolean parameter on the `jobs/users-imports` endpoint, but this parameter is not currently supported in the auth0-python package.  I've added support for this parameter, making it `False` by default so existing users should not be impacted.  I also updated unit tests for jobs to honor this change.

@Annyv2 could you please review this PR and let me know if I need to change anything?


Patch:
diff --git a/auth0/v3/management/jobs.py b/auth0/v3/management/jobs.py
index de7f543..3a24414 100644
--- a/auth0/v3/management/jobs.py
+++ b/auth0/v3/management/jobs.py
@@ -41,7 +41,7 @@ class Jobs(object):
         url = self._url('%s/errors' % (id))
         return self.client.get(url)
 
-    def import_users(self, connection_id, file_obj):
+    def import_users(self, connection_id, file_obj, upsert=False):
         """Imports users to a connection from a file.
 
         Args:
@@ -51,8 +51,13 @@ class Jobs(object):
             file_obj (file): A file-like object to upload. The format for
                 this file is explained in: https://auth0.com/docs/bulk-import
         """
+
+        # This conversion is necessary because the requests library will convert True to 'True'.
+        # The Management API only respects 'true'
+        upsert = str(upsert).lower()
+
         return self.client.file_post(self._url('users-imports'),
-                                     data={'connection_id': connection_id},
+                                     data={'connection_id': connection_id, 'upsert': upsert},
                                      files={'users': file_obj})
 
     def send_verification_email(self, body):


Test patch:
diff --git a/auth0/v3/test/management/test_jobs.py b/auth0/v3/test/management/test_jobs.py
index f9fff70..3238cee 100644
--- a/auth0/v3/test/management/test_jobs.py
+++ b/auth0/v3/test/management/test_jobs.py
@@ -36,7 +36,21 @@ class TestJobs(unittest.TestCase):
 
         mock_instance.file_post.assert_called_with(
             'https://domain/api/v2/jobs/users-imports',
-            data={'connection_id': '1234'},
+            data={'connection_id': '1234', 'upsert': 'false'},
+            files={'users': {}}
+        )
+
+        j.import_users(connection_id='1234', file_obj={}, upsert=True)
+        mock_instance.file_post.assert_called_with(
+            'https://domain/api/v2/jobs/users-imports',
+            data={'connection_id': '1234', 'upsert': 'true'},
+            files={'users': {}}
+        )
+
+        j.import_users(connection_id='1234', file_obj={}, upsert=False)
+        mock_instance.file_post.assert_called_with(
+            'https://domain/api/v2/jobs/users-imports',
+            data={'connection_id': '1234', 'upsert': 'false'},
             files={'users': {}}
         )