github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/integration/suites/harness/agent_test.go (about) 1 // Copyright (c) 2022, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package harness 6 7 import ( 8 "context" 9 "sync" 10 "testing" 11 "time" 12 13 "github.com/choria-io/go-choria/choria" 14 "github.com/choria-io/go-choria/client/rpcutilclient" 15 "github.com/choria-io/go-choria/config" 16 "github.com/choria-io/go-choria/integration/agentharness" 17 "github.com/choria-io/go-choria/integration/testbroker" 18 "github.com/choria-io/go-choria/integration/testutil" 19 "github.com/choria-io/go-choria/inter" 20 "github.com/choria-io/go-choria/internal/fs" 21 "github.com/choria-io/go-choria/providers/agent/mcorpc" 22 "github.com/choria-io/go-choria/server" 23 "github.com/golang/mock/gomock" 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 "github.com/onsi/gomega/gbytes" 27 "github.com/sirupsen/logrus" 28 ) 29 30 func TestAgentHarnessAgent(t *testing.T) { 31 RegisterFailHandler(Fail) 32 RunSpecs(t, "Integration/Agent Testing Harness") 33 } 34 35 var _ = Describe("testing harness agent", func() { 36 var ( 37 ctx context.Context 38 cancel context.CancelFunc 39 wg sync.WaitGroup 40 srv *server.Instance 41 rpcutilAgent *agentharness.AgentHarness 42 rpcutilClient *rpcutilclient.RpcutilClient 43 brokerLogger *logrus.Logger 44 brokerLogbuff *gbytes.Buffer 45 serverLogbuff *gbytes.Buffer 46 mockCtl *gomock.Controller 47 err error 48 ) 49 50 startServerInstance := func(cfgFile string, logbuff *gbytes.Buffer) (*server.Instance, error) { 51 logger := logrus.New() 52 logger.SetOutput(logbuff) 53 54 srv, err = testutil.StartServerInstance(ctx, &wg, cfgFile, logger, testutil.ServerWithDiscovery()) 55 Expect(err).ToNot(HaveOccurred()) 56 57 Eventually(logbuff).Should(gbytes.Say("Connected to nats://localhost:4222")) 58 Eventually(logbuff).Should(gbytes.Say("Registering new agent discovery of type discovery")) 59 60 return srv, nil 61 } 62 63 createAgent := func(fw inter.Framework) *mcorpc.Agent { 64 ddl, err := fs.FS.ReadFile("ddl/cache/agent/rpcutil.json") 65 Expect(err).ToNot(HaveOccurred()) 66 67 rpcutilAgent, err = agentharness.NewWithDDLBytes(fw, mockCtl, "rpcutil", ddl) 68 Expect(err).ToNot(HaveOccurred()) 69 70 a, err := rpcutilAgent.Agent() 71 Expect(err).ToNot(HaveOccurred()) 72 73 return a 74 } 75 76 createRpcUtilClient := func() (*gbytes.Buffer, *rpcutilclient.RpcutilClient, error) { 77 logBuff, logger := testutil.GbytesLogger(logrus.DebugLevel) 78 79 cfg, err := config.NewConfig("testdata/client.conf") 80 if err != nil { 81 return nil, nil, err 82 } 83 84 cfg.CustomLogger = logger 85 cfg.OverrideCertname = "rip.mcollective" 86 87 fw, err := choria.NewWithConfig(cfg) 88 if err != nil { 89 return nil, nil, err 90 } 91 92 client, err := rpcutilclient.New(fw) 93 if err != nil { 94 return nil, nil, err 95 } 96 97 return logBuff, client, nil 98 } 99 100 BeforeEach(func() { 101 mockCtl = gomock.NewController(GinkgoT()) 102 103 ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) 104 DeferCleanup(func() { 105 cancel() 106 Eventually(brokerLogbuff, 5).Should(gbytes.Say("Choria Network Broker shut down")) 107 }) 108 109 brokerLogbuff, brokerLogger = testutil.GbytesLogger(logrus.DebugLevel) 110 serverLogbuff = gbytes.NewBuffer() 111 112 _, err := testbroker.StartNetworkBrokerWithConfigFile(ctx, &wg, "testdata/broker.conf", brokerLogger) 113 Expect(err).ToNot(HaveOccurred()) 114 Eventually(brokerLogbuff, 1).Should(gbytes.Say("Server is ready")) 115 116 srv, err = startServerInstance("testdata/server.conf", serverLogbuff) 117 Expect(err).ToNot(HaveOccurred()) 118 119 err = srv.AgentManager().RegisterAgent(ctx, "rpcutil", createAgent(srv.Choria()), srv.Connector()) 120 Expect(err).ToNot(HaveOccurred()) 121 122 Eventually(serverLogbuff).Should(gbytes.Say("Registering new agent rpcutil of type rpcutil")) 123 124 _, rpcutilClient, err = createRpcUtilClient() 125 Expect(err).ToNot(HaveOccurred()) 126 }) 127 128 AfterEach(func() { 129 mockCtl.Finish() 130 }) 131 132 Describe("action stubbing", func() { 133 It("Should do the correct stubs", FlakeAttempts(5), func() { 134 rpcutilAgent.Stub("ping", func(_ context.Context, _ *mcorpc.Request, reply *mcorpc.Reply, _ *mcorpc.Agent, _ inter.ConnectorInfo) { 135 reply.Data = map[string]any{ 136 "pong": time.Now().Unix(), 137 } 138 }).AnyTimes() 139 140 for i := 0; i < 5; i++ { 141 res, err := rpcutilClient.OptionFactFilter("hello=world").Ping().Do(ctx) 142 Expect(err).ToNot(HaveOccurred()) 143 Expect(res.Stats().OKCount()).To(Equal(1)) 144 r := res.AllOutputs()[0] 145 Expect(err).ToNot(HaveOccurred()) 146 Expect(r.Pong()).To(BeNumerically("==", time.Now().Unix(), 1)) 147 } 148 149 // checks that the server did indeed sent back 10 - 5+discovery replies ie. round trip calls all happened 150 // we check for >= 10 since flake attempts will continue to increase the stats 151 Expect(srv.Stats().Replies).To(BeNumerically(">=", 10)) 152 }) 153 }) 154 })