Example #1
0
func TestSetupAgent_RPCUnixSocket_FileExists(t *testing.T) {
	conf := nextConfig()
	tmpDir, err := ioutil.TempDir("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(tmpDir)

	tmpFile, err := ioutil.TempFile("", "consul")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.Remove(tmpFile.Name())
	socketPath := tmpFile.Name()

	conf.DataDir = tmpDir
	conf.Server = true
	conf.Bootstrap = true

	// Set socket address to an existing file.
	conf.Addresses.RPC = "unix://" + socketPath

	// Custom mode for socket file
	conf.UnixSockets.Perms = "0777"

	shutdownCh := make(chan struct{})
	defer close(shutdownCh)

	cmd := &Command{
		ShutdownCh: shutdownCh,
		Ui:         new(cli.MockUi),
	}

	logWriter := logger.NewLogWriter(512)
	logOutput := new(bytes.Buffer)

	// Ensure the server is created
	if err := cmd.setupAgent(conf, logOutput, logWriter); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Ensure the file was replaced by the socket
	fi, err := os.Stat(socketPath)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if fi.Mode()&os.ModeSocket == 0 {
		t.Fatalf("expected socket to replace file")
	}

	// Ensure permissions were applied to the socket file
	if fi.Mode().String() != "Srwxrwxrwx" {
		t.Fatalf("bad permissions: %s", fi.Mode())
	}
}
Example #2
0
func testAgentWithConfig(t *testing.T, cb func(c *agent.Config)) *agentWrapper {
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	lw := logger.NewLogWriter(512)
	mult := io.MultiWriter(os.Stderr, lw)

	conf := nextConfig()
	cb(conf)

	dir, err := ioutil.TempDir("", "agent")
	if err != nil {
		t.Fatalf(fmt.Sprintf("err: %v", err))
	}
	conf.DataDir = dir

	a, err := agent.Create(conf, lw, nil, nil)
	if err != nil {
		os.RemoveAll(dir)
		t.Fatalf(fmt.Sprintf("err: %v", err))
	}

	rpc := agent.NewAgentRPC(a, l, mult, lw)

	conf.Addresses.HTTP = "127.0.0.1"
	httpAddr := fmt.Sprintf("127.0.0.1:%d", conf.Ports.HTTP)
	http, err := agent.NewHTTPServers(a, conf, os.Stderr)
	if err != nil {
		os.RemoveAll(dir)
		t.Fatalf(fmt.Sprintf("err: %v", err))
	}

	if http == nil || len(http) == 0 {
		os.RemoveAll(dir)
		t.Fatalf(fmt.Sprintf("Could not create HTTP server to listen on: %s", httpAddr))
	}

	return &agentWrapper{
		dir:      dir,
		config:   conf,
		agent:    a,
		rpc:      rpc,
		http:     http[0],
		addr:     l.Addr().String(),
		httpAddr: httpAddr,
	}
}
Example #3
0
func TestAgent_Monitor(t *testing.T) {
	logWriter := logger.NewLogWriter(512)
	logger := io.MultiWriter(os.Stdout, logWriter)

	dir, srv := makeHTTPServerWithConfigLog(t, nil, logger, logWriter)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	// Try passing an invalid log level
	req, _ := http.NewRequest("GET", "/v1/agent/monitor?loglevel=invalid", nil)
	resp := newClosableRecorder()
	if _, err := srv.AgentMonitor(resp, req); err != nil {
		t.Fatalf("err: %v", err)
	}
	if resp.Code != 400 {
		t.Fatalf("bad: %v", resp.Code)
	}
	body, _ := ioutil.ReadAll(resp.Body)
	if !strings.Contains(string(body), "Unknown log level") {
		t.Fatalf("bad: %s", body)
	}

	// Try to stream logs until we see the expected log line
	expected := []byte("raft: Initial configuration (index=1)")
	testutil.WaitForResult(func() (bool, error) {
		req, _ = http.NewRequest("GET", "/v1/agent/monitor?loglevel=debug", nil)
		resp = newClosableRecorder()
		done := make(chan struct{})
		go func() {
			if _, err := srv.AgentMonitor(resp, req); err != nil {
				t.Fatalf("err: %s", err)
			}
			close(done)
		}()

		resp.Close()
		<-done

		if bytes.Contains(resp.Body.Bytes(), expected) {
			return true, nil
		} else {
			return false, fmt.Errorf("didn't see expected")
		}
	}, func(err error) {
		t.Fatalf("err: %v", err)
	})
}
Example #4
0
func testRPCClientWithConfig(t *testing.T, cb func(c *Config)) *rpcParts {
	lw := logger.NewLogWriter(512)
	mult := io.MultiWriter(os.Stderr, lw)

	configTry := 0
RECONF:
	configTry += 1
	conf := nextConfig()
	cb(conf)

	rpcAddr, err := conf.ClientListener(conf.Addresses.RPC, conf.Ports.RPC)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	l, err := net.Listen(rpcAddr.Network(), rpcAddr.String())
	if err != nil {
		if configTry < 3 {
			goto RECONF
		}
		t.Fatalf("err: %s", err)
	}

	dir, agent := makeAgentLog(t, conf, mult, lw)
	rpc := NewAgentRPC(agent, l, mult, lw)

	rpcClient, err := NewRPCClient(l.Addr().String())
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	return &rpcParts{
		dir:    dir,
		client: rpcClient,
		agent:  agent,
		rpc:    rpc,
	}
}
Example #5
0
func TestHTTPAgent_Monitor(t *testing.T) {
	logWriter := logger.NewLogWriter(512)
	logger := io.MultiWriter(os.Stdout, logWriter)

	dir, srv := makeHTTPServerWithConfigLog(t, nil, logger, logWriter)
	defer os.RemoveAll(dir)
	defer srv.Shutdown()
	defer srv.agent.Shutdown()

	// Try passing an invalid log level
	req, _ := http.NewRequest("GET", "/v1/agent/monitor?loglevel=invalid", nil)
	resp := newClosableRecorder()
	if _, err := srv.AgentMonitor(resp, req); err != nil {
		t.Fatalf("err: %v", err)
	}
	if resp.Code != 400 {
		t.Fatalf("bad: %v", resp.Code)
	}
	body, _ := ioutil.ReadAll(resp.Body)
	if !strings.Contains(string(body), "Unknown log level") {
		t.Fatalf("bad: %s", body)
	}

	// Begin streaming logs from the monitor endpoint
	req, _ = http.NewRequest("GET", "/v1/agent/monitor?loglevel=debug", nil)
	resp = newClosableRecorder()
	go func() {
		if _, err := srv.AgentMonitor(resp, req); err != nil {
			t.Fatalf("err: %s", err)
		}
	}()

	// Write the incoming logs from http to a channel for comparison
	logCh := make(chan string, 5)

	// Block until the first log entry from http
	testutil.WaitForResult(func() (bool, error) {
		line, err := resp.Body.ReadString('\n')
		if err != nil && err != io.EOF {
			return false, fmt.Errorf("err: %v", err)
		}
		if line == "" {
			return false, fmt.Errorf("blank line")
		}
		logCh <- line
		return true, nil
	}, func(err error) {
		t.Fatal(err)
	})

	go func() {
		for {
			line, err := resp.Body.ReadString('\n')
			if err != nil && err != io.EOF {
				t.Fatalf("err: %v", err)
			}
			if line != "" {
				logCh <- line
			}
		}
	}()

	// Wait until we see the expected log line
	expected := "raft: Initial configuration (index=1)"
	testutil.WaitForResult(func() (bool, error) {
		select {
		case log := <-logCh:
			if !strings.Contains(log, expected) {
				return false, fmt.Errorf("Log message does not match expected")
			}
		case <-time.After(10 * time.Second):
			return false, fmt.Errorf("failed to get log within timeout")
		}
		return true, nil
	}, func(err error) {
		t.Fatal(err)
	})
}