Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 118 additions & 97 deletions test/integration/managementplane/config_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,143 +15,164 @@ import (
"github.com/nginx/agent/v3/test/integration/utils"

mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)

const (
configApplyErrorMessage = "failed to parse config invalid " +
"number of arguments in \"worker_processes\" directive in /etc/nginx/nginx.conf:1"
)

func TestGrpc_ConfigApply(t *testing.T) {
ctx := context.Background()
teardownTest := utils.SetupConnectionTest(t, false, false, false,
type ConfigApplyTestSuite struct {
suite.Suite
ctx context.Context
teardownTest func(testing.TB)
nginxInstanceID string
}

type ConfigApplyChunkingTestSuite struct {
suite.Suite
ctx context.Context
teardownTest func(testing.TB)
nginxInstanceID string
}

func (s *ConfigApplyTestSuite) SetupSuite() {
s.ctx = context.Background()
s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false,
"../../config/agent/nginx-config-with-grpc-client.conf")
defer teardownTest(t)
s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress)
responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress)
s.Require().Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Require().Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
}

nginxInstanceID := utils.VerifyConnection(t, 2, utils.MockManagementPlaneAPIAddress)
func (s *ConfigApplyTestSuite) TearDownSuite() {
s.teardownTest(s.T())
}

responses := utils.ManagementPlaneResponses(t, 1, utils.MockManagementPlaneAPIAddress)
assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
func (s *ConfigApplyTestSuite) TearDownTest() {
utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress)
}

t.Run("Test 1: No config changes", func(t *testing.T) {
utils.ClearManagementPlaneResponses(t, utils.MockManagementPlaneAPIAddress)
utils.PerformConfigApply(t, nginxInstanceID, utils.MockManagementPlaneAPIAddress)
responses = utils.ManagementPlaneResponses(t, 1, utils.MockManagementPlaneAPIAddress)
t.Logf("Config apply responses: %v", responses)
func (s *ConfigApplyTestSuite) TestConfigApply_Test1_TestNoConfigChanges() {
utils.PerformConfigApply(s.T(), s.nginxInstanceID, utils.MockManagementPlaneAPIAddress)
responses := utils.ManagementPlaneResponses(s.T(), 2, utils.MockManagementPlaneAPIAddress)
s.T().Logf("Config apply responses: %v", responses)

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Config apply successful, no files to change", responses[0].GetCommandResponse().GetMessage())
})
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
s.Equal("Config apply successful, no files to change", responses[1].GetCommandResponse().GetMessage())
}

t.Run("Test 2: Valid config", func(t *testing.T) {
utils.ClearManagementPlaneResponses(t, utils.MockManagementPlaneAPIAddress)
newConfigFile := "../../config/nginx/nginx-with-test-location.conf"
func (s *ConfigApplyTestSuite) TestConfigApply_Test2_TestValidConfig() {
newConfigFile := "../../config/nginx/nginx-with-test-location.conf"

if os.Getenv("IMAGE_PATH") == "/nginx-plus/agent" {
newConfigFile = "../../config/nginx/nginx-plus-with-test-location.conf"
}
if os.Getenv("IMAGE_PATH") == "/nginx-plus/agent" {
newConfigFile = "../../config/nginx/nginx-plus-with-test-location.conf"
}
err := utils.MockManagementPlaneGrpcContainer.CopyFileToContainer(
s.ctx,
newConfigFile,
fmt.Sprintf("/mock-management-plane-grpc/config/%s/etc/nginx/nginx.conf", s.nginxInstanceID),
0o666,
)
s.Require().NoError(err)

err := utils.MockManagementPlaneGrpcContainer.CopyFileToContainer(
ctx,
newConfigFile,
fmt.Sprintf("/mock-management-plane-grpc/config/%s/etc/nginx/nginx.conf", nginxInstanceID),
0o666,
)
require.NoError(t, err)
utils.PerformConfigApply(s.T(), s.nginxInstanceID, utils.MockManagementPlaneAPIAddress)
responses := utils.ManagementPlaneResponses(s.T(), 2, utils.MockManagementPlaneAPIAddress)
s.T().Logf("Config apply responses: %v", responses)

utils.PerformConfigApply(t, nginxInstanceID, utils.MockManagementPlaneAPIAddress)
sort.Slice(responses, func(i, j int) bool {
return responses[i].GetCommandResponse().GetMessage() < responses[j].GetCommandResponse().GetMessage()
})

responses = utils.ManagementPlaneResponses(t, 2, utils.MockManagementPlaneAPIAddress)
t.Logf("Config apply responses: %v", responses)
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Equal("Config apply successful", responses[0].GetCommandResponse().GetMessage())
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
s.Equal("Successfully updated all files", responses[1].GetCommandResponse().GetMessage())
}

sort.Slice(responses, func(i, j int) bool {
return responses[i].GetCommandResponse().GetMessage() < responses[j].GetCommandResponse().GetMessage()
})
func (s *ConfigApplyTestSuite) TestConfigApply_Test3_TestInvalidConfig() {
err := utils.MockManagementPlaneGrpcContainer.CopyFileToContainer(
s.ctx,
"../../config/nginx/invalid-nginx.conf",
fmt.Sprintf("/mock-management-plane-grpc/config/%s/etc/nginx/nginx.conf", s.nginxInstanceID),
0o666,
)
s.Require().NoError(err)

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Config apply successful", responses[0].GetCommandResponse().GetMessage())
assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[1].GetCommandResponse().GetMessage())
})
utils.PerformConfigApply(s.T(), s.nginxInstanceID, utils.MockManagementPlaneAPIAddress)

t.Run("Test 3: Invalid config", func(t *testing.T) {
utils.ClearManagementPlaneResponses(t, utils.MockManagementPlaneAPIAddress)
err := utils.MockManagementPlaneGrpcContainer.CopyFileToContainer(
ctx,
"../../config/nginx/invalid-nginx.conf",
fmt.Sprintf("/mock-management-plane-grpc/config/%s/etc/nginx/nginx.conf", nginxInstanceID),
0o666,
)
require.NoError(t, err)

utils.PerformConfigApply(t, nginxInstanceID, utils.MockManagementPlaneAPIAddress)

responses = utils.ManagementPlaneResponses(t, 2, utils.MockManagementPlaneAPIAddress)
t.Logf("Config apply responses: %v", responses)

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_ERROR, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Config apply failed, rolling back config", responses[0].GetCommandResponse().GetMessage())
assert.Equal(t, configApplyErrorMessage, responses[0].GetCommandResponse().GetError())
assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[1].GetCommandResponse().GetStatus())
assert.Equal(t, "Config apply failed, rollback successful", responses[1].GetCommandResponse().GetMessage())
assert.Equal(t, configApplyErrorMessage, responses[1].GetCommandResponse().GetError())
})
responses := utils.ManagementPlaneResponses(s.T(), 2, utils.MockManagementPlaneAPIAddress)
s.T().Logf("Config apply responses: %v", responses)

t.Run("Test 4: File not in allowed directory", func(t *testing.T) {
utils.ClearManagementPlaneResponses(t, utils.MockManagementPlaneAPIAddress)
utils.PerformInvalidConfigApply(t, nginxInstanceID)
s.Equal(mpi.CommandResponse_COMMAND_STATUS_ERROR, responses[0].GetCommandResponse().GetStatus())
s.Equal("Config apply failed, rolling back config", responses[0].GetCommandResponse().GetMessage())
s.Equal(configApplyErrorMessage, responses[0].GetCommandResponse().GetError())
s.Equal(mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[1].GetCommandResponse().GetStatus())
s.Equal("Config apply failed, rollback successful", responses[1].GetCommandResponse().GetMessage())
s.Equal(configApplyErrorMessage, responses[1].GetCommandResponse().GetError())
}

responses = utils.ManagementPlaneResponses(t, 1, utils.MockManagementPlaneAPIAddress)
t.Logf("Config apply responses: %v", responses)
func (s *ConfigApplyTestSuite) TestConfigApply_Test4_TestFileNotInAllowedDirectory() {
utils.PerformInvalidConfigApply(s.T(), s.nginxInstanceID)

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Config apply failed", responses[0].GetCommandResponse().GetMessage())
assert.Equal(
t,
"file not in allowed directories /unknown/nginx.conf",
responses[0].GetCommandResponse().GetError(),
)
})
responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress)
s.T().Logf("Config apply responses: %v", responses)

s.Equal(mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus())
s.Equal("Config apply failed", responses[0].GetCommandResponse().GetMessage())
s.Equal(
"file not in allowed directories /unknown/nginx.conf",
responses[0].GetCommandResponse().GetError(),
)
}

func TestGrpc_ConfigApply_Chunking(t *testing.T) {
ctx := context.Background()
teardownTest := utils.SetupConnectionTest(t, false, false, false,
func (s *ConfigApplyChunkingTestSuite) SetupSuite() {
s.ctx = context.Background()
s.teardownTest = utils.SetupConnectionTest(s.T(), false, false, false,
"../../config/agent/nginx-config-with-max-file-size.conf")
defer teardownTest(t)

nginxInstanceID := utils.VerifyConnection(t, 2, utils.MockManagementPlaneAPIAddress)
s.nginxInstanceID = utils.VerifyConnection(s.T(), 2, utils.MockManagementPlaneAPIAddress)
responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress)
s.Require().Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Require().Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
}

responses := utils.ManagementPlaneResponses(t, 1, utils.MockManagementPlaneAPIAddress)
assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
func (s *ConfigApplyChunkingTestSuite) TearDownSuite() {
s.teardownTest(s.T())
}

utils.ClearManagementPlaneResponses(t, utils.MockManagementPlaneAPIAddress)
func (s *ConfigApplyChunkingTestSuite) TestConfigApplyChunking() {
utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress)

newConfigFile := "../../config/nginx/nginx-1mb-file.conf"

err := utils.MockManagementPlaneGrpcContainer.CopyFileToContainer(
ctx,
s.ctx,
newConfigFile,
fmt.Sprintf("/mock-management-plane-grpc/config/%s/etc/nginx/nginx.conf", nginxInstanceID),
fmt.Sprintf("/mock-management-plane-grpc/config/%s/etc/nginx/nginx.conf", s.nginxInstanceID),
0o666,
)
require.NoError(t, err)
s.Require().NoError(err)

utils.PerformConfigApply(t, nginxInstanceID, utils.MockManagementPlaneAPIAddress)
utils.PerformConfigApply(s.T(), s.nginxInstanceID, utils.MockManagementPlaneAPIAddress)

responses = utils.ManagementPlaneResponses(t, 2, utils.MockManagementPlaneAPIAddress)
t.Logf("Config apply responses: %v", responses)
responses := utils.ManagementPlaneResponses(s.T(), 2, utils.MockManagementPlaneAPIAddress)
s.T().Logf("Config apply responses: %v", responses)

sort.Slice(responses, func(i, j int) bool {
return responses[i].GetCommandResponse().GetMessage() < responses[j].GetCommandResponse().GetMessage()
})

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Config apply successful", responses[0].GetCommandResponse().GetMessage())
assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[1].GetCommandResponse().GetMessage())
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Equal("Config apply successful", responses[0].GetCommandResponse().GetMessage())
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
s.Equal("Successfully updated all files", responses[1].GetCommandResponse().GetMessage())
}

func TestConfigApplyTestSuite(t *testing.T) {
suite.Run(t, new(ConfigApplyTestSuite))
suite.Run(t, new(ConfigApplyChunkingTestSuite))
}
59 changes: 39 additions & 20 deletions test/integration/managementplane/config_upload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package managementplane

import (
"context"
"fmt"
"net/http"
"testing"
Expand All @@ -14,23 +15,37 @@ import (

"github.com/go-resty/resty/v2"
mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)

func TestGrpc_ConfigUpload(t *testing.T) {
teardownTest := utils.SetupConnectionTest(t, true, false, false,
"../../config/agent/nginx-config-with-grpc-client.conf")
defer teardownTest(t)
type MPITestSuite struct {
suite.Suite
ctx context.Context
teardownTest func(testing.TB)
nginxInstanceID string
}

nginxInstanceID := utils.VerifyConnection(t, 2, utils.MockManagementPlaneAPIAddress)
assert.False(t, t.Failed())
func (s *MPITestSuite) TearDownSuite() {
s.teardownTest(s.T())
}

responses := utils.ManagementPlaneResponses(t, 1, utils.MockManagementPlaneAPIAddress)
func (s *MPITestSuite) TearDownTest() {
utils.ClearManagementPlaneResponses(s.T(), utils.MockManagementPlaneAPIAddress)
}

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
func (s *MPITestSuite) SetupSuite() {
s.ctx = context.Background()
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)
responses := utils.ManagementPlaneResponses(s.T(), 1, utils.MockManagementPlaneAPIAddress)
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage())

s.False(s.T().Failed())
}

func (s *MPITestSuite) TestConfigUpload() {
request := fmt.Sprintf(`{
"message_meta": {
"message_id": "5d0fa83e-351c-4009-90cd-1f2acce2d184",
Expand All @@ -44,9 +59,9 @@ func TestGrpc_ConfigUpload(t *testing.T) {
}
}
}
}`, nginxInstanceID)
}`, s.nginxInstanceID)

t.Logf("Sending config upload request: %s", request)
s.T().Logf("Sending config upload request: %s", request)

client := resty.New()
client.SetRetryCount(utils.RetryCount).SetRetryWaitTime(utils.RetryWaitTime).SetRetryMaxWaitTime(
Expand All @@ -55,13 +70,17 @@ func TestGrpc_ConfigUpload(t *testing.T) {
url := fmt.Sprintf("http://%s/api/v1/requests", utils.MockManagementPlaneAPIAddress)
resp, err := client.R().EnableTrace().SetBody(request).Post(url)

require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode())
s.Require().NoError(err)
s.Equal(http.StatusOK, resp.StatusCode())

responses = utils.ManagementPlaneResponses(t, 2, utils.MockManagementPlaneAPIAddress)
responses := utils.ManagementPlaneResponses(s.T(), 2, utils.MockManagementPlaneAPIAddress)

s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
s.Equal("Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
s.Equal(mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
s.Equal("Successfully updated all files", responses[1].GetCommandResponse().GetMessage())
}

assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[0].GetCommandResponse().GetMessage())
assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus())
assert.Equal(t, "Successfully updated all files", responses[1].GetCommandResponse().GetMessage())
func TestMPITestSuite(t *testing.T) {
suite.Run(t, new(MPITestSuite))
}
Loading