Esempio n. 1
0
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)
}
Esempio n. 2
0
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)
}
Esempio n. 3
0
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, "")
}