Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for plugin scaffold command #613

Merged
merged 11 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 3 additions & 4 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ jobs:
go-version: "1.23"

- name: Lint code with golangci-lint 🚨
uses: golangci/golangci-lint-action@v4
uses: golangci/golangci-lint-action@v6
with:
version: "v1.60.3"
skip-pkg-cache: true
version: "latest"
install-mode: "goinstall"

- name: Lint Bash script with shellcheck 🚨
Expand All @@ -82,7 +81,7 @@ jobs:
dockerfile: Dockerfile

- name: Run Go tests 🔬
run: go test -p 1 -cover -covermode atomic -coverprofile=profile.cov -v ./...
run: go test -tags embed_plugin_template -p 1 -cover -covermode atomic -coverprofile=profile.cov -v ./...
env:
GITHUB_AUTH_TOKEN: ${{ secrets.INTEGRATION }}

Expand Down
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ linters-settings:
- "github.com/testcontainers/testcontainers-go"
- "github.com/redis/go-redis/v9"
- "github.com/docker/go-connections/nat"
- "github.com/codingsince1985/checksum"
tagalign:
align: false
sort: false
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ clean:
@rm -rf dist

test:
@go test -v -cover -coverprofile=c.out ./...
@go test -tags embed_plugin_template -v -cover -coverprofile=c.out ./...

test-race:
@go test -race -v ./...
Expand Down
8 changes: 8 additions & 0 deletions cmd/cmd_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"

Expand Down Expand Up @@ -44,3 +45,10 @@ func mustPullPlugin() (string, error) {

return filepath.Abs(fileName) //nolint:wrapcheck
}

// runCommand runs a command in a given directory.
func runCommand(dir string, command string, args ...string) error {
cmd := exec.Command(command, args...)
cmd.Dir = dir
return cmd.Run() //nolint:wrapcheck
}
128 changes: 128 additions & 0 deletions cmd/plugin_scaffold_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package cmd

import (
"context"
"os"
"path/filepath"
"sync"
"testing"
"time"

"github.com/codingsince1985/checksum"
"github.com/gatewayd-io/gatewayd/config"
"github.com/gatewayd-io/gatewayd/plugin"
"github.com/gatewayd-io/gatewayd/testhelpers"
"github.com/spf13/cast"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
yamlv3 "gopkg.in/yaml.v3"
)

func Test_pluginScaffoldCmd(t *testing.T) {
// Start the test containers.
ctx := context.Background()
postgresHostIP1, postgresMappedPort1 := testhelpers.SetupPostgreSQLTestContainer(ctx, t)
postgresHostIP2, postgresMappedPort2 := testhelpers.SetupPostgreSQLTestContainer(ctx, t)
postgresAddress1 := postgresHostIP1 + ":" + postgresMappedPort1.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgresAddress1)
postgresAddress2 := postgresHostIP2 + ":" + postgresMappedPort2.Port()
t.Setenv("GATEWAYD_CLIENTS_TEST_WRITE_ADDRESS", postgresAddress2)

globalTestConfigFile := filepath.Join("testdata", "gatewayd.yaml")
plugin.IsPluginTemplateEmbedded()
pluginTestScaffoldInputFile := "./testdata/scaffold_input.yaml"

tempDir := t.TempDir()

output, err := executeCommandC(
rootCmd, "plugin", "scaffold", "-i", pluginTestScaffoldInputFile, "-o", tempDir)
require.NoError(t, err, "plugin scaffold should not return an error")
assert.Contains(t, output, "scaffold done")
assert.Contains(t, output, "created files:")
assert.Contains(t, output, "test-gatewayd-plugin/.github/issue_template.md")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use test-gateway-plugin multiple times, we can have a valuable for it like
pluginDir := filepath.Join(t.TempDir(), "test-gatewayd-plugin")

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use t.TempDir() to avoid polluting the working directory - https://pkg.go.dev/testing#B.TempDir

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in d7cf221.

assert.Contains(t, output, "test-gatewayd-plugin/.github/pull_request_template.md")
assert.Contains(t, output, "test-gatewayd-plugin/.github/workflows/commits-signed.yaml")

pluginName := "test-gatewayd-plugin"
pluginDir := filepath.Join(tempDir, pluginName)

pluginsConfig, err := os.ReadFile(filepath.Join(pluginDir, "gatewayd_plugin.yaml"))
require.NoError(t, err, "reading plugins config file should not return an error")

var localPluginsConfig map[string]interface{}
err = yamlv3.Unmarshal(pluginsConfig, &localPluginsConfig)
require.NoError(t, err, "unmarshalling yaml file should not return error")

err = runCommand(pluginDir, "go", "mod", "tidy")
require.NoError(t, err, "running go mod tidy should not return an error")
err = runCommand(pluginDir, "make", "build-dev")
require.NoError(t, err, "running make build-dev should not return an error")

pluginBinaryPath := filepath.Join(pluginDir, pluginName)

_, err = os.Stat(pluginBinaryPath)
require.NoError(t, err, "plugin binary file should exist")

pluginsList := cast.ToSlice(localPluginsConfig["plugins"])
plugin := cast.ToStringMap(pluginsList[0])
plugin["localPath"] = filepath.Join("cmd", pluginDir, pluginName)
sum, err := checksum.SHA256sum(pluginBinaryPath)
require.NoError(t, err, "marshalling yaml file should not return error")
plugin["checksum"] = sum

pluginsList[0] = plugin
plugins := make(map[string]interface{})
plugins["plugins"] = pluginsList

updatedPluginConfig, err := yamlv3.Marshal(plugins)
require.NoError(t, err, "marshalling yaml file should not return error")

err = os.WriteFile(
filepath.Join(pluginDir, "gatewayd_plugins.yaml"),
updatedPluginConfig, FilePermissions)
require.NoError(t, err, "writingh to yaml file should not return error")

pluginTestConfigFile := filepath.Join(pluginDir, "gatewayd_plugins.yaml")

stopChan = make(chan struct{})

var waitGroup sync.WaitGroup

waitGroup.Add(1)
go func(waitGroup *sync.WaitGroup) {
// Test run command.
output, err := executeCommandC(
rootCmd, "run", "-c", globalTestConfigFile, "-p", pluginTestConfigFile)
require.NoError(t, err, "run command should not have returned an error")

// Print the output for debugging purposes.
runCmd.Print(output)
// Check if GatewayD started and stopped correctly.
assert.Contains(t, output, "GatewayD is running")
assert.Contains(t, output, "Stopped all servers")

waitGroup.Done()
}(&waitGroup)

waitGroup.Add(1)
go func(waitGroup *sync.WaitGroup) {
time.Sleep(waitBeforeStop)

StopGracefully(
context.Background(),
nil,
nil,
metricsServer,
nil,
loggers[config.Default],
servers,
stopChan,
nil,
nil,
)

waitGroup.Done()
}(&waitGroup)

waitGroup.Wait()
}
20 changes: 10 additions & 10 deletions cmd/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ var (

func Test_runCmd(t *testing.T) {
postgresHostIP, postgresMappedPort := testhelpers.SetupPostgreSQLTestContainer(context.Background(), t)
postgredAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgredAddress)
postgresAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgresAddress)

globalTestConfigFile := "./test_global_runCmd.yaml"
pluginTestConfigFile := "./test_plugins_runCmd.yaml"
Expand Down Expand Up @@ -84,8 +84,8 @@ func Test_runCmd(t *testing.T) {
// Test_runCmdWithTLS tests the run command with TLS enabled on the server.
func Test_runCmdWithTLS(t *testing.T) {
postgresHostIP, postgresMappedPort := testhelpers.SetupPostgreSQLTestContainer(context.Background(), t)
postgredAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgredAddress)
postgresAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgresAddress)

globalTLSTestConfigFile := "./testdata/gatewayd_tls.yaml"
pluginTestConfigFile := "./test_plugins_runCmdWithTLS.yaml"
Expand Down Expand Up @@ -144,11 +144,11 @@ func Test_runCmdWithTLS(t *testing.T) {
// Test_runCmdWithMultiTenancy tests the run command with multi-tenancy enabled.
func Test_runCmdWithMultiTenancy(t *testing.T) {
postgresHostIP, postgresMappedPort := testhelpers.SetupPostgreSQLTestContainer(context.Background(), t)
postgredAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgredAddress)
postgresAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgresAddress)
postgresHostIP2, postgresMappedPort2 := testhelpers.SetupPostgreSQLTestContainer(context.Background(), t)
postgredAddress2 := postgresHostIP2 + ":" + postgresMappedPort2.Port()
t.Setenv("GATEWAYD_CLIENTS_TEST_WRITE_ADDRESS", postgredAddress2)
postgresAddress2 := postgresHostIP2 + ":" + postgresMappedPort2.Port()
t.Setenv("GATEWAYD_CLIENTS_TEST_WRITE_ADDRESS", postgresAddress2)

globalTestConfigFile := "./testdata/gatewayd.yaml"
pluginTestConfigFile := "./test_plugins_runCmdWithMultiTenancy.yaml"
Expand Down Expand Up @@ -208,8 +208,8 @@ func Test_runCmdWithMultiTenancy(t *testing.T) {

func Test_runCmdWithCachePlugin(t *testing.T) {
postgresHostIP, postgresMappedPort := testhelpers.SetupPostgreSQLTestContainer(context.Background(), t)
postgredAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgredAddress)
postgresAddress := postgresHostIP + ":" + postgresMappedPort.Port()
t.Setenv("GATEWAYD_CLIENTS_DEFAULT_WRITES_ADDRESS", postgresAddress)

globalTestConfigFile := "./test_global_runCmdWithCachePlugin.yaml"
pluginTestConfigFile := "./test_plugins_runCmdWithCachePlugin.yaml"
Expand Down
6 changes: 6 additions & 0 deletions cmd/testdata/scaffold_input.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
remote_url: https://github.com/gatewayd-io/test-gatewayd-plugin
version: 0.1
description: This is test plugin
license: MIT
authors:
- GatewayD Team
2 changes: 1 addition & 1 deletion config/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const (
// Plugin constants.
DefaultMinPort = 50000
DefaultMaxPort = 60000
PluginPriorityStart = 1000
PluginPriorityStart = uint(1000)
DefaultPluginAddress = "http://plugins/metrics"
DefaultMetricsMergerPeriod = 5 * time.Second
DefaultPluginHealthCheckPeriod = 5 * time.Second
Expand Down
2 changes: 1 addition & 1 deletion network/roundrobin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestRoundRobin_ConcurrentAccess(t *testing.T) {

waitGroup.Wait()
nextIndex := roundRobin.next.Load()
if nextIndex != uint32(numGoroutines) { //nolint:gosec
if nextIndex != uint32(numGoroutines) {
t.Errorf("expected next index to be %d, got %d", numGoroutines, nextIndex)
}
}
Expand Down
2 changes: 1 addition & 1 deletion network/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func (s *Server) OnClose(conn *ConnWrapper, err error) Action {

// Shutdown the server if there are no more connections and the server is stopped.
// This is used to shut down the server gracefully.
if uint64(s.CountConnections()) == 0 && !s.IsRunning() {
if s.CountConnections() == 0 && !s.IsRunning() {
span.AddEvent("Shutting down the server")
return Shutdown
}
Expand Down
2 changes: 1 addition & 1 deletion plugin/.template/input.example.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
remote_url: https://github.com/gatewayd/test-gatewayd-plugin
remote_url: https://github.com/gatewayd-io/test-gatewayd-plugin
version: 0.1
description: This is test plugin
license: MIT
Expand Down
3 changes: 2 additions & 1 deletion plugin/plugin_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ func (reg *Registry) LoadPlugins(
// in the config file. Built-in plugins are loaded first, followed by user-defined
// plugins. Built-in plugins have a priority of 0 to 999, and user-defined plugins
// have a priority of 1000 or greater.
plugin.Priority = sdkPlugin.Priority(config.PluginPriorityStart + uint(priority))
plugin.Priority = sdkPlugin.Priority(
config.PluginPriorityStart + uint(priority)) //nolint:gosec

logAdapter := logging.NewHcLogAdapter(&reg.Logger, pCfg.Name)

Expand Down
2 changes: 1 addition & 1 deletion plugin/plugin_registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func BenchmarkHookRun(b *testing.B) {
args.Fields["test"] = v1.NewStringValue("test1")
return args, nil
}
for priority := range 1000 {
for priority := range uint(1000) {
reg.AddHook(v1.HookName_HOOK_NAME_ON_NEW_LOGGER,
sdkPlugin.Priority(priority),
hookFunction,
Expand Down