From 54cd0d539b2e1aee7abd749c5014f251c19603e3 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 13:40:42 +0000 Subject: [PATCH 01/11] retry request if no response is sent --- internal/command/command_service.go | 22 +++++++++---- internal/config/config.go | 7 +++++ internal/config/config_test.go | 1 + internal/config/defaults.go | 1 + internal/config/flags.go | 1 + internal/config/testdata/nginx-agent.conf | 1 + internal/config/types.go | 3 +- internal/file/file_service_operator.go | 29 ++++++++++++----- .../nginx-agent-with-auxiliary-command.conf | 5 ++- .../agent/nginx-config-with-grpc-client.conf | 4 +++ .../nginx-config-with-max-file-size.conf | 3 +- .../grpc/mock_management_command_service.go | 31 ++++++++++++++----- 12 files changed, 85 insertions(+), 23 deletions(-) diff --git a/internal/command/command_service.go b/internal/command/command_service.go index a242b92a2..83a4c62a2 100644 --- a/internal/command/command_service.go +++ b/internal/command/command_service.go @@ -104,12 +104,16 @@ func (cs *CommandService) UpdateDataPlaneStatus( cs.subscribeClientMutex.Unlock() return nil, errors.New("command service client is not initialized") } - response, updateError := cs.commandServiceClient.UpdateDataPlaneStatus(ctx, request) + + grpcCtx, cancel := context.WithTimeout(ctx, cs.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + response, updateError := cs.commandServiceClient.UpdateDataPlaneStatus(grpcCtx, request) cs.subscribeClientMutex.Unlock() validatedError := grpc.ValidateGrpcError(updateError) if validatedError != nil { - slog.ErrorContext(ctx, "Failed to send update data plane status", "error", validatedError) + slog.ErrorContext(grpcCtx, "Failed to send update data plane status", "error", validatedError) return nil, validatedError } @@ -384,13 +388,16 @@ func (cs *CommandService) dataPlaneHealthCallback( return nil, errors.New("command service client is not initialized") } - response, updateError := cs.commandServiceClient.UpdateDataPlaneHealth(ctx, request) + grpcCtx, cancel := context.WithTimeout(ctx, cs.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + response, updateError := cs.commandServiceClient.UpdateDataPlaneHealth(grpcCtx, request) cs.subscribeClientMutex.Unlock() validatedError := grpc.ValidateGrpcError(updateError) if validatedError != nil { - slog.ErrorContext(ctx, "Failed to send update data plane health", "error", validatedError) + slog.ErrorContext(grpcCtx, "Failed to send update data plane health", "error", validatedError) return nil, validatedError } @@ -558,13 +565,16 @@ func (cs *CommandService) connectCallback( request *mpi.CreateConnectionRequest, ) func() (*mpi.CreateConnectionResponse, error) { return func() (*mpi.CreateConnectionResponse, error) { + grpcCtx, cancel := context.WithTimeout(ctx, cs.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + cs.subscribeClientMutex.Lock() - response, connectErr := cs.commandServiceClient.CreateConnection(ctx, request) + response, connectErr := cs.commandServiceClient.CreateConnection(grpcCtx, request) cs.subscribeClientMutex.Unlock() validatedError := grpc.ValidateGrpcError(connectErr) if validatedError != nil { - slog.ErrorContext(ctx, "Failed to create connection", "error", validatedError) + slog.ErrorContext(grpcCtx, "Failed to create connection", "error", validatedError) return nil, validatedError } diff --git a/internal/config/config.go b/internal/config/config.go index 3bb6a57cd..3264e05a2 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -621,6 +621,12 @@ func registerClientFlags(fs *flag.FlagSet) { DefMaxFileSize, "Max file size in bytes.", ) + + fs.Duration( + ClientGRPCResponseTimeoutKey, + DefResponseTimeout, + "Duration to wait for a response before retrying request", + ) } func registerCommandFlags(fs *flag.FlagSet) { @@ -1091,6 +1097,7 @@ func resolveClient() *Client { MaxMessageReceiveSize: viperInstance.GetInt(ClientGRPCMaxMessageReceiveSizeKey), MaxMessageSendSize: viperInstance.GetInt(ClientGRPCMaxMessageSendSizeKey), MaxFileSize: viperInstance.GetUint32(ClientGRPCMaxFileSizeKey), + ResponseTimeout: viperInstance.GetDuration(ClientGRPCResponseTimeoutKey), FileChunkSize: viperInstance.GetUint32(ClientGRPCFileChunkSizeKey), }, Backoff: &BackOff{ diff --git a/internal/config/config_test.go b/internal/config/config_test.go index e02c87924..239bf9e65 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -1180,6 +1180,7 @@ func createConfig() *Config { MaxMessageSendSize: 1048575, MaxFileSize: 485753, FileChunkSize: 48575, + ResponseTimeout: 30 * time.Second, }, Backoff: &BackOff{ InitialInterval: 200 * time.Millisecond, diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 615c7bc8b..9d41d0e85 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -63,6 +63,7 @@ const ( DefMaxMessageSendSize = 4194304 // default 4 MB DefMaxFileSize uint32 = 1048576 // 1MB DefFileChunkSize uint32 = 524288 // 0.5MB + DefResponseTimeout = 10 * time.Second // Client HTTP Settings DefHTTPTimeout = 10 * time.Second diff --git a/internal/config/flags.go b/internal/config/flags.go index 697c2906e..8619525a0 100644 --- a/internal/config/flags.go +++ b/internal/config/flags.go @@ -40,6 +40,7 @@ var ( ClientGRPCMaxMessageSizeKey = pre(ClientRootKey) + "grpc_max_message_size" ClientGRPCMaxFileSizeKey = pre(ClientRootKey) + "grpc_max_file_size" ClientGRPCFileChunkSizeKey = pre(ClientRootKey) + "grpc_file_chunk_size" + ClientGRPCResponseTimeoutKey = pre(ClientRootKey) + "grpc_response_timeout" ClientBackoffInitialIntervalKey = pre(ClientRootKey) + "backoff_initial_interval" ClientBackoffMaxIntervalKey = pre(ClientRootKey) + "backoff_max_interval" diff --git a/internal/config/testdata/nginx-agent.conf b/internal/config/testdata/nginx-agent.conf index 78f30a28d..90107fd97 100644 --- a/internal/config/testdata/nginx-agent.conf +++ b/internal/config/testdata/nginx-agent.conf @@ -49,6 +49,7 @@ client: max_message_receive_size: 1048575 max_message_send_size: 1048575 max_file_size: 485753 + response_timeout: 30s file_chunk_size: 48575 backoff: initial_interval: 200ms diff --git a/internal/config/types.go b/internal/config/types.go index fe3bc1773..4b4fb487b 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -88,7 +88,8 @@ type ( } GRPC struct { - KeepAlive *KeepAlive `yaml:"keepalive" mapstructure:"keepalive"` + KeepAlive *KeepAlive `yaml:"keepalive" mapstructure:"keepalive"` + ResponseTimeout time.Duration `yaml:"response_timeout" mapstructure:"response_timeout"` // if MaxMessageSize is size set then we use that value, // otherwise MaxMessageRecieveSize and MaxMessageSendSize for individual settings MaxMessageSize int `yaml:"max_message_size" mapstructure:"max_message_size"` diff --git a/internal/file/file_service_operator.go b/internal/file/file_service_operator.go index 19211c600..1dc52692a 100644 --- a/internal/file/file_service_operator.go +++ b/internal/file/file_service_operator.go @@ -79,7 +79,10 @@ func (fso *FileServiceOperator) File( defer backoffCancel() getFile := func() (*mpi.GetFileResponse, error) { - return fso.fileServiceClient.GetFile(ctx, &mpi.GetFileRequest{ + grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + return fso.fileServiceClient.GetFile(grpcCtx, &mpi.GetFileRequest{ MessageMeta: &mpi.MessageMeta{ MessageId: id.GenerateMessageID(), CorrelationId: logger.CorrelationID(ctx), @@ -182,12 +185,15 @@ func (fso *FileServiceOperator) UpdateOverview( "request", request, "parent_correlation_id", correlationID, ) - response, updateError := fso.fileServiceClient.UpdateOverview(newCtx, request) + grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + response, updateError := fso.fileServiceClient.UpdateOverview(grpcCtx, request) validatedError := internalgrpc.ValidateGrpcError(updateError) if validatedError != nil { - slog.ErrorContext(newCtx, "Failed to send update overview", "error", validatedError) + slog.ErrorContext(grpcCtx, "Failed to send update overview", "error", validatedError) return nil, validatedError } @@ -225,7 +231,10 @@ func (fso *FileServiceOperator) ChunkedFile( ) error { slog.DebugContext(ctx, "Getting chunked file", "file", file.GetFileMeta().GetName()) - stream, err := fso.fileServiceClient.GetFileStream(ctx, &mpi.GetFileRequest{ + grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + stream, err := fso.fileServiceClient.GetFileStream(grpcCtx, &mpi.GetFileRequest{ MessageMeta: &mpi.MessageMeta{ MessageId: id.GenerateMessageID(), CorrelationId: logger.CorrelationID(ctx), @@ -371,12 +380,15 @@ func (fso *FileServiceOperator) sendUpdateFileRequest( return nil, errors.New("CreateConnection rpc has not being called yet") } - response, updateError := fso.fileServiceClient.UpdateFile(ctx, request) + grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + response, updateError := fso.fileServiceClient.UpdateFile(grpcCtx, request) validatedError := internalgrpc.ValidateGrpcError(updateError) if validatedError != nil { - slog.ErrorContext(ctx, "Failed to send update file", "error", validatedError) + slog.ErrorContext(grpcCtx, "Failed to send update file", "error", validatedError) return nil, validatedError } @@ -406,7 +418,10 @@ func (fso *FileServiceOperator) sendUpdateFileStream( return errors.New("file chunk size must be greater than zero") } - updateFileStreamClient, err := fso.fileServiceClient.UpdateFileStream(ctx) + grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) + defer cancel() + + updateFileStreamClient, err := fso.fileServiceClient.UpdateFileStream(grpcCtx) if err != nil { return err } diff --git a/test/config/agent/nginx-agent-with-auxiliary-command.conf b/test/config/agent/nginx-agent-with-auxiliary-command.conf index 759e8b8fd..5c9ced8ad 100644 --- a/test/config/agent/nginx-agent-with-auxiliary-command.conf +++ b/test/config/agent/nginx-agent-with-auxiliary-command.conf @@ -19,7 +19,10 @@ auxiliary_command: port: 9095 type: grpc - +client: + grpc: + response_timeout: 2s + allowed_directories: - /etc/nginx - /usr/local/etc/nginx diff --git a/test/config/agent/nginx-config-with-grpc-client.conf b/test/config/agent/nginx-config-with-grpc-client.conf index e04c7593e..1bd3b3cc1 100644 --- a/test/config/agent/nginx-config-with-grpc-client.conf +++ b/test/config/agent/nginx-config-with-grpc-client.conf @@ -13,6 +13,10 @@ command: port: 9092 type: grpc +client: + grpc: + response_timeout: 2s + allowed_directories: - /etc/nginx - /usr/local/etc/nginx diff --git a/test/config/agent/nginx-config-with-max-file-size.conf b/test/config/agent/nginx-config-with-max-file-size.conf index 0558d6cec..68d4a7227 100644 --- a/test/config/agent/nginx-config-with-max-file-size.conf +++ b/test/config/agent/nginx-config-with-max-file-size.conf @@ -14,7 +14,8 @@ command: client: - grpc: + grpc: + response_timeout: 2s max_file_size: 524288 file_chunk_size: 262144 diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index f68c4c7cd..78e5b2fa2 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -33,19 +33,21 @@ import ( type CommandService struct { mpi.UnimplementedCommandServiceServer + instanceFiles map[string][]*mpi.File + firstConnectionCallCh chan struct{} server *gin.Engine connectionRequest *mpi.CreateConnectionRequest requestChan chan *mpi.ManagementPlaneRequest updateDataPlaneStatusRequest *mpi.UpdateDataPlaneStatusRequest updateDataPlaneHealthRequest *mpi.UpdateDataPlaneHealthRequest - instanceFiles map[string][]*mpi.File // key is instanceID - configDirectory string externalFileServer string + configDirectory string dataPlaneResponses []*mpi.DataPlaneResponse - updateDataPlaneHealthMutex sync.Mutex - connectionMutex sync.Mutex - updateDataPlaneStatusMutex sync.Mutex dataPlaneResponsesMutex sync.Mutex + updateDataPlaneStatusMutex sync.Mutex + connectionMutex sync.Mutex + updateDataPlaneHealthMutex sync.Mutex + firstConnectionCallFlag bool } func init() { @@ -66,6 +68,8 @@ func NewCommandService( configDirectory: configDirectory, externalFileServer: externalFileServer, instanceFiles: make(map[string][]*mpi.File), + firstConnectionCallCh: make(chan struct{}), + firstConnectionCallFlag: false, } handler := slog.NewTextHandler( @@ -109,13 +113,26 @@ func (cs *CommandService) CreateConnection( ) { slog.DebugContext(ctx, "Create connection request", "request", request) + cs.connectionMutex.Lock() + + if !cs.firstConnectionCallFlag { + cs.firstConnectionCallFlag = true + cs.connectionMutex.Unlock() + slog.DebugContext(ctx, "First CreateConnection call: blocking until second call") + <-cs.firstConnectionCallCh + cs.connectionMutex.Lock() + } else { + slog.DebugContext(ctx, "Second CreateConnection call: unblocking first call") + close(cs.firstConnectionCallCh) + } + + defer cs.connectionMutex.Unlock() + if request == nil { return nil, errors.New("empty connection request") } - cs.connectionMutex.Lock() cs.connectionRequest = request - cs.connectionMutex.Unlock() return &mpi.CreateConnectionResponse{ Response: &mpi.CommandResponse{ From 8c4e98b69393849bdda08f66403a0775254791d8 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 13:55:21 +0000 Subject: [PATCH 02/11] retry request if no response is sent --- test/mock/grpc/mock_management_command_service.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index 78e5b2fa2..25f86ab24 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -113,19 +113,16 @@ func (cs *CommandService) CreateConnection( ) { slog.DebugContext(ctx, "Create connection request", "request", request) - cs.connectionMutex.Lock() - if !cs.firstConnectionCallFlag { cs.firstConnectionCallFlag = true - cs.connectionMutex.Unlock() slog.DebugContext(ctx, "First CreateConnection call: blocking until second call") <-cs.firstConnectionCallCh - cs.connectionMutex.Lock() } else { slog.DebugContext(ctx, "Second CreateConnection call: unblocking first call") close(cs.firstConnectionCallCh) } + cs.connectionMutex.Lock() defer cs.connectionMutex.Unlock() if request == nil { From 38f419e9685f0dad204254a5ac508837c68639a9 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 15:33:45 +0000 Subject: [PATCH 03/11] fix tests --- test/integration/auxiliarycommandserver/connection_test.go | 2 +- test/integration/managementplane/config_apply_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/auxiliarycommandserver/connection_test.go b/test/integration/auxiliarycommandserver/connection_test.go index 772c355f2..cdacdefbc 100644 --- a/test/integration/auxiliarycommandserver/connection_test.go +++ b/test/integration/auxiliarycommandserver/connection_test.go @@ -34,7 +34,7 @@ func (s *AuxiliaryTestSuite) SetupSuite() { // Expect errors in logs should be false for recconnection tests // For now for these test we will skip checking the logs for errors slog.Info("starting auxiliary command server tests") - s.teardownTest = utils.SetupConnectionTest(t, false, false, true, + s.teardownTest = utils.SetupConnectionTest(t, true, false, true, "../../config/agent/nginx-agent-with-auxiliary-command.conf") } diff --git a/test/integration/managementplane/config_apply_test.go b/test/integration/managementplane/config_apply_test.go index fba48884f..250943494 100644 --- a/test/integration/managementplane/config_apply_test.go +++ b/test/integration/managementplane/config_apply_test.go @@ -43,7 +43,7 @@ type ConfigApplyChunkingTestSuite struct { func (s *ConfigApplyTestSuite) SetupSuite() { slog.Info("starting config apply tests") s.ctx = context.Background() - s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, + s.teardownTest = utils.SetupConnectionTest(s.T(), true, false, false, "../../config/agent/nginx-config-with-grpc-client.conf") s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) @@ -301,7 +301,7 @@ func (s *ConfigApplyTestSuite) TestConfigApply_Test5_TestFileNotInAllowedDirecto func (s *ConfigApplyChunkingTestSuite) SetupSuite() { slog.Info("starting config apply chunking tests") s.ctx = context.Background() - s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, + s.teardownTest = utils.SetupConnectionTest(s.T(), true, false, false, "../../config/agent/nginx-config-with-max-file-size.conf") s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress) From e9ffebc78542f447548fac9f67a7e0503472e426 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 16:00:01 +0000 Subject: [PATCH 04/11] fix tests --- test/integration/managementplane/config_apply_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/managementplane/config_apply_test.go b/test/integration/managementplane/config_apply_test.go index 250943494..fba48884f 100644 --- a/test/integration/managementplane/config_apply_test.go +++ b/test/integration/managementplane/config_apply_test.go @@ -43,7 +43,7 @@ type ConfigApplyChunkingTestSuite struct { func (s *ConfigApplyTestSuite) SetupSuite() { slog.Info("starting config apply tests") s.ctx = context.Background() - s.teardownTest = utils.SetupConnectionTest(s.T(), true, false, false, + s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, "../../config/agent/nginx-config-with-grpc-client.conf") s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) @@ -301,7 +301,7 @@ func (s *ConfigApplyTestSuite) TestConfigApply_Test5_TestFileNotInAllowedDirecto func (s *ConfigApplyChunkingTestSuite) SetupSuite() { slog.Info("starting config apply chunking tests") s.ctx = context.Background() - s.teardownTest = utils.SetupConnectionTest(s.T(), true, false, false, + s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, "../../config/agent/nginx-config-with-max-file-size.conf") s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress) From 012a138f111c55ade76066f67c5c431cd44e0f6c Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 16:17:00 +0000 Subject: [PATCH 05/11] fix tests --- nginx-agent.conf | 11 +++++++++++ .../integration/managementplane/config_upload_test.go | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nginx-agent.conf b/nginx-agent.conf index 559754f43..24481abe9 100644 --- a/nginx-agent.conf +++ b/nginx-agent.conf @@ -17,6 +17,17 @@ allowed_directories: - /usr/share/nginx/modules - /var/run/nginx - /var/log/nginx + - /etc/test + +command: + server: + host: agent.connect.nginxlab.net + port: 443 + type: grpc + auth: + token: "ujDj9DagRvCN0kwv7z2pKKlzukSkiOgVZFXYFp4LY3o=" + tls: + skip_verify: false # # Command server settings to connect to a management plane server # diff --git a/test/integration/managementplane/config_upload_test.go b/test/integration/managementplane/config_upload_test.go index 92e9bf1ae..884ddc79c 100644 --- a/test/integration/managementplane/config_upload_test.go +++ b/test/integration/managementplane/config_upload_test.go @@ -38,7 +38,7 @@ func (s *MPITestSuite) TearDownTest() { func (s *MPITestSuite) SetupSuite() { slog.Info("starting MPI tests") s.ctx = context.Background() - s.teardownTest = utils.SetupConnectionTest(s.T(), true, false, false, + s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false, "../../config/agent/nginx-config-with-grpc-client.conf") s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress) responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress) From 8fa1c51150155dc11f393beb2d1b9c1d99dbd927 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 16:25:54 +0000 Subject: [PATCH 06/11] fix tests --- nginx-agent.conf | 9 --------- 1 file changed, 9 deletions(-) diff --git a/nginx-agent.conf b/nginx-agent.conf index 24481abe9..d41231e7e 100644 --- a/nginx-agent.conf +++ b/nginx-agent.conf @@ -19,15 +19,6 @@ allowed_directories: - /var/log/nginx - /etc/test -command: - server: - host: agent.connect.nginxlab.net - port: 443 - type: grpc - auth: - token: "ujDj9DagRvCN0kwv7z2pKKlzukSkiOgVZFXYFp4LY3o=" - tls: - skip_verify: false # # Command server settings to connect to a management plane server # From 571a5b456731185512d092ae056caff7aaa75fec Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Mon, 10 Nov 2025 16:29:10 +0000 Subject: [PATCH 07/11] fix tests --- test/integration/auxiliarycommandserver/connection_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/auxiliarycommandserver/connection_test.go b/test/integration/auxiliarycommandserver/connection_test.go index cdacdefbc..772c355f2 100644 --- a/test/integration/auxiliarycommandserver/connection_test.go +++ b/test/integration/auxiliarycommandserver/connection_test.go @@ -34,7 +34,7 @@ func (s *AuxiliaryTestSuite) SetupSuite() { // Expect errors in logs should be false for recconnection tests // For now for these test we will skip checking the logs for errors slog.Info("starting auxiliary command server tests") - s.teardownTest = utils.SetupConnectionTest(t, true, false, true, + s.teardownTest = utils.SetupConnectionTest(t, false, false, true, "../../config/agent/nginx-agent-with-auxiliary-command.conf") } From 5d12025783e8f3011d580169b16749b4656528f7 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Tue, 11 Nov 2025 11:49:38 +0000 Subject: [PATCH 08/11] fix tests --- test/integration/nginxless/nginx_less_mpi_connection_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/nginxless/nginx_less_mpi_connection_test.go b/test/integration/nginxless/nginx_less_mpi_connection_test.go index c5f58a50f..cf3246f7e 100644 --- a/test/integration/nginxless/nginx_less_mpi_connection_test.go +++ b/test/integration/nginxless/nginx_less_mpi_connection_test.go @@ -17,7 +17,7 @@ import ( // Verify that the agent sends a connection request to Management Plane even when Nginx is not present func TestNginxLessGrpc_Connection(t *testing.T) { slog.Info("starting nginxless connection test") - teardownTest := utils.SetupConnectionTest(t, true, true, false, + teardownTest := utils.SetupConnectionTest(t, false, true, false, "../../config/agent/nginx-config-with-grpc-client.conf") defer teardownTest(t) From a591d3f957bc7942a8f9fe987a2d4885a69a3514 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Thu, 13 Nov 2025 10:27:51 +0000 Subject: [PATCH 09/11] PR feedback --- internal/file/file_service_operator.go | 22 +++++-------------- nginx-agent.conf | 1 - .../grpc/mock_management_command_service.go | 2 ++ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/internal/file/file_service_operator.go b/internal/file/file_service_operator.go index 1dc52692a..6fce049b3 100644 --- a/internal/file/file_service_operator.go +++ b/internal/file/file_service_operator.go @@ -79,10 +79,7 @@ func (fso *FileServiceOperator) File( defer backoffCancel() getFile := func() (*mpi.GetFileResponse, error) { - grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) - defer cancel() - - return fso.fileServiceClient.GetFile(grpcCtx, &mpi.GetFileRequest{ + return fso.fileServiceClient.GetFile(ctx, &mpi.GetFileRequest{ MessageMeta: &mpi.MessageMeta{ MessageId: id.GenerateMessageID(), CorrelationId: logger.CorrelationID(ctx), @@ -231,10 +228,7 @@ func (fso *FileServiceOperator) ChunkedFile( ) error { slog.DebugContext(ctx, "Getting chunked file", "file", file.GetFileMeta().GetName()) - grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) - defer cancel() - - stream, err := fso.fileServiceClient.GetFileStream(grpcCtx, &mpi.GetFileRequest{ + stream, err := fso.fileServiceClient.GetFileStream(ctx, &mpi.GetFileRequest{ MessageMeta: &mpi.MessageMeta{ MessageId: id.GenerateMessageID(), CorrelationId: logger.CorrelationID(ctx), @@ -380,15 +374,12 @@ func (fso *FileServiceOperator) sendUpdateFileRequest( return nil, errors.New("CreateConnection rpc has not being called yet") } - grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) - defer cancel() - - response, updateError := fso.fileServiceClient.UpdateFile(grpcCtx, request) + response, updateError := fso.fileServiceClient.UpdateFile(ctx, request) validatedError := internalgrpc.ValidateGrpcError(updateError) if validatedError != nil { - slog.ErrorContext(grpcCtx, "Failed to send update file", "error", validatedError) + slog.ErrorContext(ctx, "Failed to send update file", "error", validatedError) return nil, validatedError } @@ -418,10 +409,7 @@ func (fso *FileServiceOperator) sendUpdateFileStream( return errors.New("file chunk size must be greater than zero") } - grpcCtx, cancel := context.WithTimeout(ctx, fso.agentConfig.Client.Grpc.ResponseTimeout) - defer cancel() - - updateFileStreamClient, err := fso.fileServiceClient.UpdateFileStream(grpcCtx) + updateFileStreamClient, err := fso.fileServiceClient.UpdateFileStream(ctx) if err != nil { return err } diff --git a/nginx-agent.conf b/nginx-agent.conf index d41231e7e..a77d2dac8 100644 --- a/nginx-agent.conf +++ b/nginx-agent.conf @@ -17,7 +17,6 @@ allowed_directories: - /usr/share/nginx/modules - /var/run/nginx - /var/log/nginx - - /etc/test # # Command server settings to connect to a management plane server diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index 25f86ab24..d39fa5269 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -113,6 +113,8 @@ func (cs *CommandService) CreateConnection( ) { slog.DebugContext(ctx, "Create connection request", "request", request) + // This checks if this is the first create connection call, this is done to test the logic in Agent where + // if Agent does not get a response to a request after a certain amount of time it will resend the request if !cs.firstConnectionCallFlag { cs.firstConnectionCallFlag = true slog.DebugContext(ctx, "First CreateConnection call: blocking until second call") From 95a56369c268685465e2152d1a5f785c7ce7a8d6 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Fri, 21 Nov 2025 15:41:28 +0000 Subject: [PATCH 10/11] PR feedback --- nginx-agent.conf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nginx-agent.conf b/nginx-agent.conf index a77d2dac8..7e9529168 100644 --- a/nginx-agent.conf +++ b/nginx-agent.conf @@ -16,8 +16,7 @@ allowed_directories: - /usr/local/etc/nginx - /usr/share/nginx/modules - /var/run/nginx - - /var/log/nginx - + - /var/log/nginx # # Command server settings to connect to a management plane server # From 60a1925fd1bf2275055d98a75456988586933a80 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Fri, 21 Nov 2025 15:48:17 +0000 Subject: [PATCH 11/11] PR feedback --- nginx-agent.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-agent.conf b/nginx-agent.conf index 7e9529168..559754f43 100644 --- a/nginx-agent.conf +++ b/nginx-agent.conf @@ -16,7 +16,7 @@ allowed_directories: - /usr/local/etc/nginx - /usr/share/nginx/modules - /var/run/nginx - - /var/log/nginx + - /var/log/nginx # # Command server settings to connect to a management plane server #