github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/providers/agent/mcorpc/ruby/agent_test.go (about) 1 // Copyright (c) 2020-2022, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package ruby 6 7 import ( 8 "context" 9 "io" 10 "path/filepath" 11 "runtime" 12 13 "github.com/choria-io/go-choria/build" 14 "github.com/choria-io/go-choria/choria" 15 "github.com/choria-io/go-choria/config" 16 "github.com/choria-io/go-choria/inter" 17 "github.com/choria-io/go-choria/providers/agent/mcorpc" 18 ddl "github.com/choria-io/go-choria/providers/agent/mcorpc/ddl/agent" 19 "github.com/golang/mock/gomock" 20 . "github.com/onsi/ginkgo/v2" 21 . "github.com/onsi/gomega" 22 "github.com/sirupsen/logrus" 23 ) 24 25 var _ = Describe("McoRPC/Ruby", func() { 26 var ( 27 mockctl *gomock.Controller 28 agentMgr *MockAgentManager 29 cfg *config.Config 30 fw *choria.Framework 31 err error 32 logger *logrus.Entry 33 agent *mcorpc.Agent 34 ) 35 36 BeforeEach(func() { 37 build.TLS = "false" 38 39 l := logrus.New() 40 l.Out = io.Discard 41 logger = l.WithFields(logrus.Fields{}) 42 43 mockctl = gomock.NewController(GinkgoT()) 44 agentMgr = NewMockAgentManager(mockctl) 45 46 cfg = config.NewConfigForTests() 47 cfg.DisableSecurityProviderVerify = true 48 49 fw, err = choria.NewWithConfig(cfg) 50 Expect(err).ToNot(HaveOccurred()) 51 52 agentMgr.EXPECT().Choria().Return(fw).AnyTimes() 53 agentMgr.EXPECT().Logger().Return(logger).AnyTimes() 54 }) 55 56 AfterEach(func() { 57 mockctl.Finish() 58 }) 59 60 Describe("rubyAction", func() { 61 var req *mcorpc.Request 62 var rep *mcorpc.Reply 63 var ctx context.Context 64 var agent *mcorpc.Agent 65 var ci inter.ConnectorInfo 66 67 BeforeEach(func() { 68 req = &mcorpc.Request{ 69 Agent: "one", 70 Action: "status", 71 } 72 73 rep = &mcorpc.Reply{} 74 ctx = context.Background() 75 76 ddl, err := ddl.New("testdata/lib1/mcollective/agent/one.json") 77 Expect(err).ToNot(HaveOccurred()) 78 79 agent, err = NewRubyAgent(ddl, agentMgr) 80 Expect(err).ToNot(HaveOccurred()) 81 }) 82 83 It("Should fail when no shim is configured", func() { 84 fw.Config.Choria.RubyAgentShim = "" 85 rubyAction(ctx, req, rep, agent, ci) 86 Expect(rep.Statuscode).To(Equal(mcorpc.Aborted)) 87 Expect(rep.Statusmsg).To(Equal("Cannot call Ruby action one#status: Ruby compatibility shim was not configured")) 88 }) 89 90 It("Should fail when the shim cannot be found", func() { 91 fw.Config.Choria.RubyAgentShim = "/nonexisting" 92 fw.Config.Choria.RubyAgentConfig = "testdata/shim.cfg" 93 rubyAction(ctx, req, rep, agent, ci) 94 Expect(rep.Statuscode).To(Equal(mcorpc.Aborted)) 95 Expect(rep.Statusmsg).To(Equal("Cannot call Ruby action one#status: Ruby compatibility shim was not found in /nonexisting")) 96 }) 97 98 It("Should fail without a shim config file", func() { 99 fw.Config.Choria.RubyAgentShim = "testdata/nonzero_shim.sh" 100 fw.Config.Choria.RubyAgentConfig = "" 101 102 rubyAction(ctx, req, rep, agent, ci) 103 Expect(rep.Statuscode).To(Equal(mcorpc.Aborted)) 104 Expect(rep.Statusmsg).To(Equal("Cannot call Ruby action one#status: Ruby compatibility shim configuration file not configured")) 105 }) 106 107 It("Should fail when a shim config file does not exist", func() { 108 fw.Config.Choria.RubyAgentShim = "testdata/nonzero_shim.sh" 109 fw.Config.Choria.RubyAgentConfig = "/nonexisting" 110 111 rubyAction(ctx, req, rep, agent, ci) 112 Expect(rep.Statuscode).To(Equal(mcorpc.Aborted)) 113 Expect(rep.Statusmsg).To(Equal("Cannot call Ruby action one#status: Ruby compatibility shim configuration file was not found in /nonexisting")) 114 }) 115 116 It("Should unmarshal the result", func() { 117 if runtime.GOOS == "windows" { 118 fw.Config.Choria.RubyAgentShim = filepath.Join("testdata", "good_shim_windows.bat") 119 } else { 120 fw.Config.Choria.RubyAgentShim = filepath.Join("testdata", "good_shim.sh") 121 } 122 123 fw.Config.Choria.RubyAgentConfig = filepath.Join("testdata", "shim.cfg") 124 125 try := 0 126 for try < 5 { 127 rubyAction(ctx, req, rep, agent, ci) 128 if rep.Statuscode == mcorpc.OK { 129 break 130 } 131 try++ 132 } 133 134 Expect(rep.Statusmsg).To(Equal("OK")) 135 Expect(rep.Statuscode).To(Equal(mcorpc.OK)) 136 137 d := rep.Data.(map[string]any) 138 Expect(d["test"].(string)).To(Equal("ok")) 139 }) 140 }) 141 142 Describe("activationCheck", func() { 143 var ( 144 d *ddl.DDL 145 err error 146 ) 147 148 BeforeEach(func() { 149 d, err = ddl.New("testdata/lib1/mcollective/agent/one.json") 150 Expect(err).ToNot(HaveOccurred()) 151 }) 152 153 It("Should respect true value activate_agent setting", func() { 154 cfg, err := config.NewConfig("testdata/one_agent_enabled.cfg") 155 Expect(err).ToNot(HaveOccurred()) 156 fw.Config = cfg 157 Expect(activationCheck(d, agentMgr)()).To(BeTrue()) 158 }) 159 160 It("Should respect false value activate_agent setting", func() { 161 cfg, err := config.NewConfig("testdata/one_agent_disabled.cfg") 162 Expect(err).ToNot(HaveOccurred()) 163 fw.Config = cfg 164 Expect(activationCheck(d, agentMgr)()).To(BeFalse()) 165 }) 166 167 It("Should default to the correct value", func() { 168 cfg, err := config.NewConfig("testdata/shim.cfg") 169 Expect(err).ToNot(HaveOccurred()) 170 fw.Config = cfg 171 Expect(activationCheck(d, agentMgr)()).To(Equal(activationDefault)) 172 }) 173 }) 174 175 Describe("NewRubyAgent", func() { 176 It("Should create a shim with all the actions mapped", func() { 177 d, err := ddl.New("testdata/lib1/mcollective/agent/one.json") 178 Expect(err).ToNot(HaveOccurred()) 179 180 agent, err = NewRubyAgent(d, agentMgr) 181 Expect(err).ToNot(HaveOccurred()) 182 183 Expect(agent.ActionNames()).To(Equal(d.ActionNames())) 184 }) 185 }) 186 })