Skip to content

Commit

Permalink
update ipc_endpoint tests
Browse files Browse the repository at this point in the history
  • Loading branch information
misteriaud committed Dec 6, 2024
1 parent ced2ebe commit b6aa3e2
Showing 1 changed file with 102 additions and 79 deletions.
181 changes: 102 additions & 79 deletions pkg/api/util/ipc_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,203 +17,226 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

configmock "github.com/DataDog/datadog-agent/pkg/config/mock"
pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model"
)

func createConfig(t *testing.T, ts *httptest.Server) pkgconfigmodel.Config {
conf := configmock.New(t)
type IPCEndpointTestSuite struct {
suite.Suite
conf pkgconfigmodel.Config
}

func TestIPCEndpointTestSuite(t *testing.T) {
// cleaning auth_token and cert globals to be able initialize again the authToken and IPC cert
token = ""
dcaToken = ""
clientTLSConfig = nil
serverTLSConfig = nil

// creating test suite
testSuite := new(IPCEndpointTestSuite)

// simulating a normal startup of Agent with auth_token and cert generation
testSuite.conf = configmock.New(t)

// create a fake auth token
authTokenFile, err := os.CreateTemp("", "")
assert.NoError(t, err)
require.NoError(t, err)
authTokenPath := authTokenFile.Name()
os.WriteFile(authTokenPath, []byte("0123456789abcdef0123456789abcdef"), 0640)
testSuite.conf.Set("auth_token_file_path", authTokenPath, pkgconfigmodel.SourceAgentRuntime)

addr, err := url.Parse(ts.URL)
assert.NoError(t, err)
localHost, localPort, _ := net.SplitHostPort(addr.Host)
// set a tmp path for the cert/key path
f, err := os.CreateTemp("", "ipc_cert")
require.NoError(t, err)
testSuite.conf.Set("ipc_cert_file_path", f.Name(), pkgconfigmodel.SourceAgentRuntime)

// set minimal configuration that IPCEndpoint needs
conf.Set("auth_token_file_path", authTokenPath, pkgconfigmodel.SourceAgentRuntime)
conf.Set("cmd_host", localHost, pkgconfigmodel.SourceAgentRuntime)
conf.Set("cmd_port", localPort, pkgconfigmodel.SourceAgentRuntime)
// use the cert in the httptest server
CreateAndSetAuthToken(testSuite.conf)

return conf
suite.Run(t, testSuite)
}

func TestNewIPCEndpoint(t *testing.T) {
conf := configmock.New(t)
func (suite *IPCEndpointTestSuite) setTestServerAndConfig(t *testing.T, ts *httptest.Server, isHTTPS bool) {
if isHTTPS {
ts.TLS = GetTLSServerConfig()
ts.StartTLS()
} else {
ts.Start()
}

// create a fake auth token
authTokenFile, err := os.CreateTemp("", "")
assert.NoError(t, err)
authTokenPath := authTokenFile.Name()
os.WriteFile(authTokenPath, []byte("0123456789abcdef0123456789abcdef"), 0640)
// use the httptest server as the CMD_API
addr, err := url.Parse(ts.URL)
require.NoError(t, err)
localHost, localPort, _ := net.SplitHostPort(addr.Host)
suite.conf.Set("cmd_host", localHost, pkgconfigmodel.SourceAgentRuntime)
suite.conf.Set("cmd_port", localPort, pkgconfigmodel.SourceAgentRuntime)
}

func (suite *IPCEndpointTestSuite) TestNewIPCEndpoint() {
t := suite.T()

// set minimal configuration that IPCEndpoint needs
conf.Set("auth_token_file_path", authTokenPath, pkgconfigmodel.SourceAgentRuntime)
conf.Set("cmd_host", "localhost", pkgconfigmodel.SourceAgentRuntime)
conf.Set("cmd_port", "6789", pkgconfigmodel.SourceAgentRuntime)
suite.conf.Set("cmd_host", "localhost", pkgconfigmodel.SourceAgentRuntime)
suite.conf.Set("cmd_port", "6789", pkgconfigmodel.SourceAgentRuntime)

// test the endpoint construction
end, err := NewIPCEndpoint(conf, "test/api")
end, err := NewIPCEndpoint(suite.conf, "test/api")
assert.NoError(t, err)
assert.Equal(t, end.target.String(), "https://localhost:6789/test/api")
}

func TestNewIPCEndpointWithCloseConnection(t *testing.T) {
conf := configmock.New(t)

// create a fake auth token
authTokenFile, err := os.CreateTemp("", "")
assert.NoError(t, err)
authTokenPath := authTokenFile.Name()
os.WriteFile(authTokenPath, []byte("0123456789abcdef0123456789abcdef"), 0640)

// set minimal configuration that IPCEndpoint needs
conf.Set("auth_token_file_path", authTokenPath, pkgconfigmodel.SourceAgentRuntime)
conf.Set("cmd_host", "localhost", pkgconfigmodel.SourceAgentRuntime)
conf.Set("cmd_port", "6789", pkgconfigmodel.SourceAgentRuntime)
func (suite *IPCEndpointTestSuite) TestNewIPCEndpointWithCloseConnection() {
t := suite.T()

// test constructing with the CloseConnection option
end, err := NewIPCEndpoint(conf, "test/api", WithCloseConnection(true))
assert.NoError(t, err)
end, err := NewIPCEndpoint(suite.conf, "test/api", WithCloseConnection(true))
require.NoError(t, err)
assert.True(t, end.closeConn)
}

func TestIPCEndpointDoGet(t *testing.T) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointDoGet() {
t := suite.T()
gotURL := ""
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotURL = r.URL.String()
_, _ = io.ReadAll(r.Body)
w.Write([]byte("ok"))
}))
defer ts.Close()

conf := createConfig(t, ts)
end, err := NewIPCEndpoint(conf, "test/api")
suite.setTestServerAndConfig(t, ts, true)
end, err := NewIPCEndpoint(suite.conf, "test/api")
assert.NoError(t, err)

// test that DoGet will hit the endpoint url
res, err := end.DoGet()
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, res, []byte("ok"))
assert.Equal(t, gotURL, "/test/api")
}

func TestIPCEndpointGetWithHTTPClientAndNonTLS(t *testing.T) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointGetWithHTTPClientAndNonTLS() {
t := suite.T()
// non-http server
gotURL := ""
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotURL = r.URL.String()
_, _ = io.ReadAll(r.Body)
w.Write([]byte("ok"))
}))
defer ts.Close()

// create non-TLS client and use the "http" protocol
suite.setTestServerAndConfig(t, ts, false)
client := http.Client{}
conf := createConfig(t, ts)
end, err := NewIPCEndpoint(conf, "test/api", WithHTTPClient(&client), WithURLScheme("http"))
end, err := NewIPCEndpoint(suite.conf, "test/api", WithHTTPClient(&client), WithURLScheme("http"))
assert.NoError(t, err)

// test that DoGet will hit the endpoint url
res, err := end.DoGet()
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, res, []byte("ok"))
assert.Equal(t, gotURL, "/test/api")
}

func TestIPCEndpointGetWithValues(t *testing.T) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointGetWithValues() {
t := suite.T()
gotURL := ""
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotURL = r.URL.String()
_, _ = io.ReadAll(r.Body)
w.Write([]byte("ok"))
}))
defer ts.Close()

conf := createConfig(t, ts)
suite.setTestServerAndConfig(t, ts, true)
// set url values for GET request
v := url.Values{}
v.Set("verbose", "true")

// test construction with option for url.Values
end, err := NewIPCEndpoint(conf, "test/api")
end, err := NewIPCEndpoint(suite.conf, "test/api")
assert.NoError(t, err)

// test that DoGet will use query parameters from the url.Values
res, err := end.DoGet(WithValues(v))
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, res, []byte("ok"))
assert.Equal(t, gotURL, "/test/api?verbose=true")
}

func TestIPCEndpointGetWithHostAndPort(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointGetWithHostAndPort() {
t := suite.T()
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = io.ReadAll(r.Body)
w.Write([]byte("ok"))
}))
defer ts.Close()

conf := createConfig(t, ts)
suite.setTestServerAndConfig(t, ts, true)
// modify the config so that it uses a different setting for the cmd_host
conf.Set("process_config.cmd_host", "127.0.0.1", pkgconfigmodel.SourceAgentRuntime)
suite.conf.Set("process_config.cmd_host", "127.0.0.1", pkgconfigmodel.SourceAgentRuntime)

// test construction with alternate values for the host and port
end, err := NewIPCEndpoint(conf, "test/api", WithHostAndPort(conf.GetString("process_config.cmd_host"), conf.GetInt("cmd_port")))
end, err := NewIPCEndpoint(suite.conf, "test/api", WithHostAndPort(suite.conf.GetString("process_config.cmd_host"), suite.conf.GetInt("cmd_port")))
assert.NoError(t, err)

// test that host provided by WithHostAndPort is used for the endpoint
res, err := end.DoGet()
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, res, []byte("ok"))
assert.Equal(t, end.target.Host, fmt.Sprintf("127.0.0.1:%d", conf.GetInt("cmd_port")))
assert.Equal(t, end.target.Host, fmt.Sprintf("127.0.0.1:%d", suite.conf.GetInt("cmd_port")))
}

func TestIPCEndpointDeprecatedIPCAddress(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointDeprecatedIPCAddress() {
t := suite.T()
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = io.ReadAll(r.Body)
w.Write([]byte("ok"))
}))
defer ts.Close()

conf := createConfig(t, ts)
suite.setTestServerAndConfig(t, ts, true)
// Use the deprecated (but still supported) option "ipc_address"
conf.UnsetForSource("cmd_host", pkgconfigmodel.SourceAgentRuntime)
conf.Set("ipc_address", "127.0.0.1", pkgconfigmodel.SourceAgentRuntime)
suite.conf.UnsetForSource("cmd_host", pkgconfigmodel.SourceAgentRuntime)
suite.conf.Set("ipc_address", "127.0.0.1", pkgconfigmodel.SourceAgentRuntime)
defer suite.conf.UnsetForSource("ipc_address", pkgconfigmodel.SourceAgentRuntime)

// test construction, uses ipc_address instead of cmd_host
end, err := NewIPCEndpoint(conf, "test/api")
end, err := NewIPCEndpoint(suite.conf, "test/api")
assert.NoError(t, err)

// test that host provided by "ipc_address" is used for the endpoint
res, err := end.DoGet()
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, res, []byte("ok"))
assert.Equal(t, end.target.Host, fmt.Sprintf("127.0.0.1:%d", conf.GetInt("cmd_port")))
assert.Equal(t, end.target.Host, fmt.Sprintf("127.0.0.1:%d", suite.conf.GetInt("cmd_port")))
}

func TestIPCEndpointErrorText(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointErrorText() {
t := suite.T()
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(400)
w.Write([]byte("bad request"))
}))
defer ts.Close()

conf := createConfig(t, ts)
end, err := NewIPCEndpoint(conf, "test/api")
assert.NoError(t, err)
suite.setTestServerAndConfig(t, ts, true)
end, err := NewIPCEndpoint(suite.conf, "test/api")
require.NoError(t, err)

// test that error is returned by the endpoint
_, err = end.DoGet()
assert.Error(t, err)
require.Error(t, err)
}

func TestIPCEndpointErrorMap(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
func (suite *IPCEndpointTestSuite) TestIPCEndpointErrorMap() {
t := suite.T()
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(400)
data, _ := json.Marshal(map[string]string{
"error": "something went wrong",
Expand All @@ -222,12 +245,12 @@ func TestIPCEndpointErrorMap(t *testing.T) {
}))
defer ts.Close()

conf := createConfig(t, ts)
end, err := NewIPCEndpoint(conf, "test/api")
assert.NoError(t, err)
suite.setTestServerAndConfig(t, ts, true)
end, err := NewIPCEndpoint(suite.conf, "test/api")
require.NoError(t, err)

// test that error gets unwrapped from the errmap
_, err = end.DoGet()
assert.Error(t, err)
require.Error(t, err)
assert.Equal(t, err.Error(), "something went wrong")
}

0 comments on commit b6aa3e2

Please sign in to comment.