func (s *AgentTestSuite) TestSetConfigApiKey(t *C) { newConfig := *s.config newConfig.ApiKey = "101" data, err := json.Marshal(newConfig) t.Assert(err, IsNil) cmd := &proto.Cmd{ Ts: time.Now(), User: "******", Cmd: "SetConfig", Service: "agent", Data: data, } s.sendChan <- cmd got := test.WaitReply(s.recvChan) t.Assert(len(got), Equals, 1) gotConfig := &agent.Config{} if err := json.Unmarshal(got[0].Data, gotConfig); err != nil { t.Fatal(err) } /** * Verify new agent config in memory. */ expect := *s.config expect.ApiKey = "101" expect.Links = nil if ok, diff := test.IsDeeply(gotConfig, &expect); !ok { t.Logf("%+v", gotConfig) t.Error(diff) } /** * Verify new agent config in API connector. */ t.Check(s.api.ApiKey(), Equals, "101") t.Check(s.api.Hostname(), Equals, agent.DEFAULT_API_HOSTNAME) /** * Verify new agent config on disk. */ data, err = ioutil.ReadFile(s.configFile) t.Assert(err, IsNil) gotConfig = &agent.Config{} if err := json.Unmarshal(data, gotConfig); err != nil { t.Fatal(err) } if same, diff := test.IsDeeply(gotConfig, &expect); !same { // @todo: if expect is not ptr, IsDeeply dies with "got ptr, expected struct" t.Logf("%+v", gotConfig) t.Error(diff) } // After changing the API key, the agent's ws should NOT reconnect yet, // but status should show that its link has changed, so sending a Reconnect // cmd will cause agent to reconnect its ws. gotCalled := test.WaitTrace(s.client.TraceChan) expectCalled := []string{"Start", "Connect"} t.Check(gotCalled, DeepEquals, expectCalled) }
func (s *AgentTestSuite) TestSetConfigApiHostname(t *C) { newConfig := *s.config newConfig.ApiHostname = "http://localhost" data, err := json.Marshal(newConfig) t.Assert(err, IsNil) cmd := &proto.Cmd{ Ts: time.Now(), User: "******", Cmd: "SetConfig", Service: "agent", Data: data, } s.sendChan <- cmd got := test.WaitReply(s.recvChan) t.Assert(len(got), Equals, 1) gotConfig := &agent.Config{} if err := json.Unmarshal(got[0].Data, gotConfig); err != nil { t.Fatal(err) } /** * Verify new agent config in memory. */ expect := *s.config expect.ApiHostname = "http://localhost" expect.Links = nil if ok, diff := test.IsDeeply(gotConfig, &expect); !ok { t.Logf("%+v", gotConfig) t.Error(diff) } /** * Verify new agent config in API connector. */ t.Check(s.api.Hostname(), Equals, "http://localhost") t.Check(s.api.ApiKey(), Equals, "789") /** * Verify new agent config on disk. */ data, err = ioutil.ReadFile(s.configFile) t.Assert(err, IsNil) gotConfig = &agent.Config{} if err := json.Unmarshal(data, gotConfig); err != nil { t.Fatal(err) } if same, diff := test.IsDeeply(gotConfig, &expect); !same { // @todo: if expect is not ptr, IsDeeply dies with "got ptr, expected struct" t.Logf("%+v", gotConfig) t.Error(diff) } // After changing the API host, the agent's ws should NOT reconnect yet, // but status should show that its link has changed, so sending a Reconnect // cmd will cause agent to reconnect its ws. gotCalled := test.WaitTrace(s.client.TraceChan) expectCalled := []string{"Start", "Connect"} t.Check(gotCalled, DeepEquals, expectCalled) /** * Test Reconnect here since it's usually done after changing ApiHostname/ */ // There is NO reply after reconnect because we can't recv cmd on one connection // and reply on another. Instead, we should see agent try to reconnect: connectChan := make(chan bool) s.client.SetConnectChan(connectChan) defer s.client.SetConnectChan(nil) cmd = &proto.Cmd{ Ts: time.Now(), User: "******", Cmd: "Reconnect", Service: "agent", } s.sendChan <- cmd // Wait for agent to reconnect. <-connectChan connectChan <- true gotCalled = test.WaitTrace(s.client.TraceChan) expectCalled = []string{"Disconnect", "Connect"} t.Check(gotCalled, DeepEquals, expectCalled) }
func (s *AgentTestSuite) TestStartStopService(t *C) { // To start a service, first we make a config for the service: qanConfig := &qan.Config{ Interval: 60, // seconds MaxSlowLogSize: 1073741824, // 1 GiB RemoveOldSlowLogs: true, ExampleQueries: true, MaxWorkers: 2, WorkerRunTime: 120, // seconds } // Second, the service config is encoded and encapsulated in a ServiceData: qanConfigData, _ := json.Marshal(qanConfig) serviceCmd := &proto.ServiceData{ Name: "qan", Config: qanConfigData, } // Third and final, the service data is encoded and encapsulated in a Cmd: serviceData, _ := json.Marshal(serviceCmd) cmd := &proto.Cmd{ Ts: time.Now(), User: "******", Service: "agent", Cmd: "StartService", Data: serviceData, } // The readyChan is used by mock.MockServiceManager.Start() and Stop() // to simulate slow starts and stops. We're not testing that here, so // this lets the service start immediately. s.readyChan <- true // Send the StartService cmd to the client, then wait for the reply // which should not have an error, indicating success. s.sendChan <- cmd gotReplies := test.WaitReply(s.recvChan) if len(gotReplies) != 1 { t.Fatal("Got Reply to Cmd:StartService") } reply := &proto.Reply{} _ = json.Unmarshal(gotReplies[0].Data, reply) if reply.Error != "" { t.Error("No Reply.Error to Cmd:StartService; got ", reply.Error) } // To double-check that the agent started without error, get its status // which should show everything is "Ready" or "Idle". status := test.GetStatus(s.sendChan, s.recvChan) expectStatus := map[string]string{ "agent": "Idle", "qan": "Ready", "mm": "", } if same, diff := test.IsDeeply(status, expectStatus); !same { t.Error(diff) } // Finally, since we're using mock objects, let's double check the // execution trace, i.e. what calls the agent made based on all // the previous ^. got := test.WaitTrace(s.traceChan) expect := []string{ `Start qan`, `Status qan`, `Status mm`, } t.Check(got, DeepEquals, expect) /** * Stop the service. */ serviceCmd = &proto.ServiceData{ Name: "qan", } serviceData, _ = json.Marshal(serviceCmd) cmd = &proto.Cmd{ Ts: time.Now(), User: "******", Service: "agent", Cmd: "StopService", Data: serviceData, } // Let fake qan service stop immediately. s.readyChan <- true s.sendChan <- cmd gotReplies = test.WaitReply(s.recvChan) if len(gotReplies) != 1 { t.Fatal("Got Reply to Cmd:StopService") } reply = &proto.Reply{} _ = json.Unmarshal(gotReplies[0].Data, reply) if reply.Error != "" { t.Error("No Reply.Error to Cmd:StopService; got ", reply.Error) } status = test.GetStatus(s.sendChan, s.recvChan) t.Check(status["agent"], Equals, "Idle") t.Check(status["qan"], Equals, "Stopped") t.Check(status["mm"], Equals, "") }