From 9727822b8a9f03eb8b6de87e40573f12ebcecc3f Mon Sep 17 00:00:00 2001 From: James Wells Date: Fri, 6 Sep 2024 06:59:19 -0700 Subject: [PATCH] Very preliminary CI/CD pipeline to see if I need to manually pull the code. --- .forgejo/workflows/build.yaml | 13 +++ assets/docker/Dockerfile | 2 +- cmd/gagent/main_test.go | 160 ++++++++++++++++++++++------------ go.mod | 19 ++-- go.sum | 36 ++++---- 5 files changed, 149 insertions(+), 81 deletions(-) create mode 100644 .forgejo/workflows/build.yaml diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml new file mode 100644 index 0000000..6e23e77 --- /dev/null +++ b/.forgejo/workflows/build.yaml @@ -0,0 +1,13 @@ +name: Build G'Agent +on: [push] +jobs: + trivy_scan: + runs-on: docker + container: + image: dragonheim/golang:latest + steps: + - run: ls -la + - run: go version + - run: go fmt + # - run: apk add --no-cache git zeromq-dev build-base + # - run: go build -o test cmd/gagent/main.go diff --git a/assets/docker/Dockerfile b/assets/docker/Dockerfile index 5031819..2a28e33 100644 --- a/assets/docker/Dockerfile +++ b/assets/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM dragonheim/golang:1.22 as builder +FROM dragonheim/golang:1.23 as builder ARG SEMVER=${SEMVER:-0.0.11} WORKDIR /gagent diff --git a/cmd/gagent/main_test.go b/cmd/gagent/main_test.go index 3efdb37..7c46d12 100644 --- a/cmd/gagent/main_test.go +++ b/cmd/gagent/main_test.go @@ -1,70 +1,120 @@ package main import ( - os "os" - testing "testing" + "bytes" + "log" + "net/http" + "net/http/httptest" + "os" + "testing" - // main "github.com/dragonheim/gagent/cmd/gagent" + env "github.com/caarlos0/env/v6" gstructs "github.com/dragonheim/gagent/internal/gstructs" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) -// This function will create a temporary config file for testing purposes -func createTestConfigFile() (string, error) { - tmpfile, err := os.CreateTemp("", "test_config_*.hcl") - if err != nil { - return "", err - } - - content := []byte(`mode = "setup" -listen_addr = "0.0.0.0" -monitor_port = 8888 -client_port = 35572 -router_port = 35570 -worker_port = 35571 -`) - if _, err := tmpfile.Write(content); err != nil { - return "", err - } - if err := tmpfile.Close(); err != nil { - return "", err - } - - return tmpfile.Name(), nil +// Mocking the WaitGroup to avoid actually waiting in tests +type MockWaitGroup struct { + mock.Mock } -func TestMain(t *testing.T) { - t.Run("Test setup mode with temp config file", func(t *testing.T) { - tmpConfig, err := createTestConfigFile() - if err != nil { - t.Fatalf("Failed to create temp config file: %v", err) - } - defer os.Remove(tmpConfig) +func (m *MockWaitGroup) Add(delta int) { + m.Called(delta) +} - config := gstructs.GagentConfig{ - File: tmpConfig, - Mode: "setup", - } +func (m *MockWaitGroup) Done() { + m.Called() +} - // Run the main function with the temporary config - t.Run(config) +func (m *MockWaitGroup) Wait() { + m.Called() +} - // Check if the config has been set up correctly - expectedConfig := gstructs.GagentConfig{ - Mode: "setup", - ListenAddr: "0.0.0.0", - MonitorPort: 8888, - ClientPort: 35572, - RouterPort: 35570, - WorkerPort: 35571, - } +// Mocking the config loader function to inject test configurations +func mockInitConfig() { + config = gstructs.GagentConfig{ + Mode: "client", + MonitorPort: 8080, + // Populate other required fields as needed + } +} - if config.Mode != expectedConfig.Mode || - config.ListenAddr != expectedConfig.ListenAddr || - config.MonitorPort != expectedConfig.MonitorPort || - config.ClientPort != expectedConfig.ClientPort || - config.RouterPort != expectedConfig.RouterPort || - config.WorkerPort != expectedConfig.WorkerPort { - t.Fatalf("Expected config %+v, got %+v", expectedConfig, config) - } +func TestMainFunction(t *testing.T) { + var wg MockWaitGroup + wg.On("Add", 1).Return() + wg.On("Wait").Return() + wg.On("Done").Return() + + mockInitConfig() + + // Test the client mode + config.Mode = "client" + main() + wg.AssertCalled(t, "Add", 1) + + // Test the router mode + config.Mode = "router" + main() + wg.AssertCalled(t, "Add", 1) + + // Test the worker mode + config.Mode = "worker" + main() + wg.AssertCalled(t, "Add", 1) + + // Test the setup mode + config.Mode = "setup" + main() + wg.AssertCalled(t, "Add", 1) + + // Test an invalid mode + config.Mode = "invalid" + assert.Panics(t, func() { main() }, "Expected main() to panic with invalid mode") +} + +func TestInitFunction(t *testing.T) { + // Backup original stdout and defer restoration + origStdout := os.Stdout + defer func() { os.Stdout = origStdout }() + + // Capture stdout output to test log output + var logOutput bytes.Buffer + log.SetOutput(&logOutput) + + // Test init + init() + + // Assertions + assert.Contains(t, logOutput.String(), "[DEBUG] Arguments are") + assert.NotEmpty(t, config.Version, "Config version should not be empty") + assert.NotEmpty(t, config.UUID, "Config UUID should not be empty") +} + +func TestPrometheusMetricsExporter(t *testing.T) { + mockInitConfig() + config.MonitorPort = 8080 + + req, err := http.NewRequest("GET", "/metrics", nil) + assert.NoError(t, err) + + rr := httptest.NewRecorder() + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.DefaultServeMux.ServeHTTP(w, r) }) + handler.ServeHTTP(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code, "Handler returned wrong status code") + assert.Contains(t, rr.Body.String(), "go_gc_duration_seconds", "Expected metrics output") +} + +func TestEnvironmentParsing(t *testing.T) { + cfg := environment + err := env.Parse(&cfg) + assert.NoError(t, err) + + assert.Equal(t, "/etc/gagent/gagent.hcl", cfg.ConfigFile, "Expected default config file path") + assert.Equal(t, "WARN", cfg.LogLevel, "Expected default log level") + assert.Equal(t, "setup", cfg.Mode, "Expected default mode") + assert.Equal(t, 0, cfg.MonitorPort, "Expected default monitor port") } diff --git a/go.mod b/go.mod index d9f8bf6..a12bdf5 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,20 @@ module github.com/dragonheim/gagent -go 1.22 +go 1.23 require ( github.com/Showmax/go-fqdn v1.0.0 github.com/aviddiviner/docopt-go v0.0.0-20170807220726-d8a1d67efc6a github.com/caarlos0/env/v6 v6.10.1 github.com/carlmjohnson/versioninfo v0.22.5 - github.com/hashicorp/hcl/v2 v2.21.0 + github.com/hashicorp/hcl/v2 v2.22.0 github.com/hashicorp/logutils v1.0.0 github.com/jakehl/goid v1.1.0 github.com/pebbe/zmq4 v1.2.11 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.20.2 github.com/slayer/autorestart v0.0.0-20170706172547-5ebd91f955ae github.com/stretchr/testify v1.9.0 - github.com/zclconf/go-cty v1.14.4 + github.com/zclconf/go-cty v1.15.0 ) require ( @@ -24,6 +24,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -31,11 +32,11 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c485511..703cde5 100644 --- a/go.sum +++ b/go.sum @@ -21,16 +21,20 @@ github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= -github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= +github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/jakehl/goid v1.1.0 h1:c08GO8z16wWJtfQhyiD8BQRFkpf1oDxaPmA+uYAG+50= github.com/jakehl/goid v1.1.0/go.mod h1:V6bQh+tr2Oay5WHL0jmTTJWrABYIO+cs4/P6e1prV1o= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -39,8 +43,8 @@ github.com/pebbe/zmq4 v1.2.11 h1:Ua5mgIaZeabUGnH7tqswkUcjkL7JYGai5e8v4hpEU9Q= github.com/pebbe/zmq4 v1.2.11/go.mod h1:nqnPueOapVhE2wItZ0uOErngczsJdLOGkebMxaO8r48= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= @@ -53,20 +57,20 @@ github.com/slayer/autorestart v0.0.0-20170706172547-5ebd91f955ae h1:hnJJroq/koox github.com/slayer/autorestart v0.0.0-20170706172547-5ebd91f955ae/go.mod h1:p+QQKBy7tS+myk+y3sgnAKx4gUtD/Q9Z6KEd77cLzWY= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=