Skip to content

Commit

Permalink
Add test for plugin scaffold command (#613)
Browse files Browse the repository at this point in the history
* Implement scaffold tests (wip)
* Fix issues
* Add test for plugin scaffold command
* Fix typo
* Add package to allow list
* Include plugin template when testing
* Address comments by @sinadarbouy
* Fix linter issues
* Remove unnecessary os.RemoveAll
* Use latest version of golangci-lint command and action
* Each call to t.TempDir return a new directory

---------

Co-authored-by: zeina1i <[email protected]>
  • Loading branch information
mostafa and zeina1i authored Oct 3, 2024
1 parent ffd13ea commit 041dc62
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 21 deletions.
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")
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

0 comments on commit 041dc62

Please sign in to comment.