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()) } }
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, } }
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) }) }
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, } }
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) }) }