diff --git a/.changelog/14599.txt b/.changelog/14599.txt new file mode 100644 index 000000000..10b36d0dd --- /dev/null +++ b/.changelog/14599.txt @@ -0,0 +1,3 @@ +```release-note:improvement +api: Increase max number of operations inside a transaction for requests to /v1/txn (128) +``` \ No newline at end of file diff --git a/agent/txn_endpoint.go b/agent/txn_endpoint.go index f528bbda4..e2f093e5d 100644 --- a/agent/txn_endpoint.go +++ b/agent/txn_endpoint.go @@ -17,7 +17,7 @@ const ( // maxTxnOps is used to set an upper limit on the number of operations // inside a transaction. If there are more operations than this, then the // client is likely abusing transactions. - maxTxnOps = 64 + maxTxnOps = 128 ) // decodeValue decodes the value member of the given operation. diff --git a/agent/txn_endpoint_test.go b/agent/txn_endpoint_test.go index f6f47b8fa..90e535995 100644 --- a/agent/txn_endpoint_test.go +++ b/agent/txn_endpoint_test.go @@ -798,3 +798,54 @@ func TestTxnEndpoint_NodeService(t *testing.T) { } assert.Equal(t, expected, txnResp) } + +func TestTxnEndpoint_OperationsSize(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + t.Run("too-many-operations", func(t *testing.T) { + var ops []api.TxnOp + agent := NewTestAgent(t, "limits = { txn_max_req_len = 700000 }") + + for i := 0; i < 130; i++ { + ops = append(ops, api.TxnOp{ + KV: &api.KVTxnOp{ + Verb: api.KVSet, + Key: "key", + Value: []byte("test"), + }, + }) + } + + req, _ := http.NewRequest("PUT", "/v1/txn", jsonBody(ops)) + resp := httptest.NewRecorder() + raw, err := agent.srv.Txn(resp, req) + require.Error(t, err) + require.Contains(t, err.Error(), "Transaction contains too many operations") + require.Nil(t, raw) + agent.Shutdown() + }) + + t.Run("allowed", func(t *testing.T) { + var ops []api.TxnOp + agent := NewTestAgent(t, "limits = { txn_max_req_len = 700000 }") + + for i := 0; i < 128; i++ { + ops = append(ops, api.TxnOp{ + KV: &api.KVTxnOp{ + Verb: api.KVSet, + Key: "key", + Value: []byte("test"), + }, + }) + } + + req, _ := http.NewRequest("PUT", "/v1/txn", jsonBody(ops)) + resp := httptest.NewRecorder() + raw, err := agent.srv.Txn(resp, req) + require.NoError(t, err) + require.NotNil(t, raw) + agent.Shutdown() + }) +}