123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- package http
- import (
- "io/ioutil"
- "net"
- "os"
- "path/filepath"
- "runtime"
- "syscall"
- "testing"
- "github.com/stretchr/testify/assert"
- )
- var socketConfigFileWithTimeouts = `
- socket = "tm.ipc"
- workdir = "qdata/c1"
- dialTimeout = 8
- timeout = 9
- `
- var socketConfigFileNoTimeouts = `
- socket = "tm.ipc"
- workdir = "qdata/c1"
- `
- var httpConfigFileWithTimeouts = `
- httpUrl = "http:localhost:9101"
- tlsMode = "OFF"
- timeout = 101
- httpIdleConnTimeout = 102
- httpWriteBufferSize = 1001
- httpReadBufferSize = 1002
- `
- var httpConfigFileWithInvalidTlsMode = `
- httpUrl = "http:localhost:9101"
- tlsMode = "ABC"
- `
- var httpTlsConfigFileWithTimeouts = `
- httpUrl = "https:localhost:9101"
- tlsMode = "STRICT"
- tlsRootCA = "mydir/rootca.cert.pem"
- tlsClientCert = "mydir/client.cert.pem"
- tlsClientKey = "mydir/client.key.pem"
- timeout = 101
- httpIdleConnTimeout = 102
- httpWriteBufferSize = 1001
- httpReadBufferSize = 1002
- `
- var httpTlsConfigFileNoTimeouts = `
- httpUrl = "https:localhost:9101"
- tlsMode = "strict"
- tlsRootCA = "mydir/rootca.cert.pem"
- tlsClientCert = "mydir/client.cert.pem"
- tlsClientKey = "mydir/client.key.pem"
- tlsInsecureSkipVerify = true
- `
- var httpTlsConfigFileNoRootCert = `
- httpUrl = "https:localhost:9101"
- tlsMode = "STRICT"
- tlsClientCert = "mydir/client.cert.pem"
- tlsClientKey = "mydir/client.key.pem"
- `
- var invalidHttpTlsConfigFileNoClientCert = `
- httpUrl = "https:localhost:9101"
- tlsMode = "STRICT"
- tlsRootCA = "mydir/rootca.cert.pem"
- `
- var invalidHttpTlsConfigFileOnlyClientCert = `
- httpUrl = "https:localhost:9101"
- tlsMode = "STRICT"
- tlsRootCA = "mydir/rootca.cert.pem"
- tlsClientCert = "mydir/client.cert.pem"
- `
- var invalidHttpTlsConfigFileOnlyClientKey = `
- httpUrl = "https:localhost:9101"
- tlsMode = "STRICT"
- tlsRootCA = "mydir/rootca.cert.pem"
- tlsClientKey = "mydir/client.key.pem"
- `
- var httpTlsConfigFileWithHTTPOnly = `
- httpUrl = "http:localhost:9101"
- tlsMode = "strict"
- tlsRootCA = "mydir/rootca.cert.pem"
- tlsClientCert = "mydir/client.cert.pem"
- tlsClientKey = "mydir/client.key.pem"
- `
- var invalidConfigWithSocketAndHttp = `
- socket = "tm.ipc"
- workdir = "qdata/c1"
- httpUrl = "http:localhost:9101"
- `
- var invalidConfigWithNoSocketOrHttp = `
- `
- func TestDefaultTimeoutsUsedWhenNoConfigFileSpecified(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("this test case is not supported for windows")
- }
- socketFile := filepath.Join(os.TempDir(), "socket-file.ipc")
- syscall.Unlink(socketFile)
- l, err := net.Listen("unix", socketFile)
- if err != nil {
- t.Fatalf("Could not create socket file '%v' for unit test, error: %v", socketFile, err)
- }
- defer l.Close()
- cfg, err := FetchConfig(socketFile)
- if assert.NoError(t, err, "Failed to retrieve socket configuration") {
- assert.True(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned false, when expecting true")
- assert.Equal(t, socketFile, filepath.Join(cfg.WorkDir, cfg.Socket), "Socket path unexpectedly changed when loading default config")
- assert.Equal(t, DefaultConfig.DialTimeout, cfg.DialTimeout, "Did not get expected socket default DialTimeout")
- assert.Equal(t, DefaultConfig.Timeout, cfg.Timeout, "Did not get expected socket default Timeout")
- }
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestLoadSocketConfigWithTimeouts(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "socketConfigFileWithTimeouts.toml")
- if err := ioutil.WriteFile(configFile, []byte(socketConfigFileWithTimeouts), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- if assert.NoError(t, err, "Failed to load config file") {
- assert.True(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned false, when expecting true")
- assert.Equal(t, "qdata/c1/tm.ipc", filepath.Join(cfg.WorkDir, cfg.Socket), "Did not get expected socket path from config file")
- assert.Equal(t, uint(8), cfg.DialTimeout, "Did not get expected socket DialTimeout from config file")
- assert.Equal(t, uint(9), cfg.Timeout, "Did not get expected socket Timeout from config file")
- }
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestLoadSocketConfigWithDefaultTimeouts(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "socketConfigFileNoTimeouts.toml")
- if err := ioutil.WriteFile(configFile, []byte(socketConfigFileNoTimeouts), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- if assert.NoError(t, err, "Failed to load config file") {
- assert.True(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned false, when expecting true")
- assert.Equal(t, DefaultConfig.DialTimeout, cfg.DialTimeout, "Did not get expected socket default DialTimeout from config file")
- assert.Equal(t, DefaultConfig.Timeout, cfg.Timeout, "Did not get expected socket default Timeout from config file")
- }
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestLoadHttpConfigWithTimeouts(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "httpConfigFileWithTimeouts.toml")
- if err := ioutil.WriteFile(configFile, []byte(httpConfigFileWithTimeouts), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- if assert.NoError(t, err, "Failed to load config file") {
- assert.False(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned true, when expecting false")
- assert.Equal(t, "http:localhost:9101", cfg.HttpUrl, "Did not get expected http url from config file")
- assert.Equal(t, cfg.TlsMode, TlsOff, "Did not get expected IsTlsConfigured() value from config file")
- assert.Equal(t, uint(101), cfg.Timeout, "Did not get expected http Timeout from config file")
- assert.Equal(t, uint(102), cfg.HttpIdleConnTimeout, "Did not get expected http HttpIdleConnTimeout from config file")
- assert.Equal(t, int(1001), cfg.HttpWriteBufferSize, "Did not get expected http HttpWriteBufferSize from config file")
- assert.Equal(t, int(1002), cfg.HttpReadBufferSize, "Did not get expected http HttpReadBufferSize from config file")
- }
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestLoadHttpConfigWithInvalidTls(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "httpConfigFileWithInvalidTlsMode.toml")
- if err := ioutil.WriteFile(configFile, []byte(httpConfigFileWithInvalidTlsMode), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "invalid value for TLS mode in config file, must be either OFF or STRICT")
- }
- }
- func TestLoadHttpTlsConfigWithTimeouts(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileWithTimeouts.toml")
- if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileWithTimeouts), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- if assert.NoError(t, err, "Failed to load config file") {
- assert.False(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned true, when expecting false")
- assert.Equal(t, "https:localhost:9101", cfg.HttpUrl, "Did not get expected http url from config file")
- assert.Equal(t, cfg.TlsMode, TlsStrict, "Did not get expected IsTlsConfigured() value from config file")
- assert.Equal(t, "mydir/rootca.cert.pem", cfg.TlsRootCA, "Did not get expected TlsRootCA from config file")
- assert.Equal(t, "mydir/client.cert.pem", cfg.TlsClientCert, "Did not get expected TlsClientCert from config file")
- assert.Equal(t, "mydir/client.key.pem", cfg.TlsClientKey, "Did not get expected TlsClientKey from config file")
- assert.Equal(t, uint(101), cfg.Timeout, "Did not get expected http Timeout from config file")
- assert.Equal(t, uint(102), cfg.HttpIdleConnTimeout, "Did not get expected http HttpIdleConnTimeout from config file")
- assert.Equal(t, int(1001), cfg.HttpWriteBufferSize, "Did not get expected http HttpWriteBufferSize from config file")
- assert.Equal(t, int(1002), cfg.HttpReadBufferSize, "Did not get expected http HttpReadBufferSize from config file")
- assert.False(t, cfg.TlsInsecureSkipVerify, "Did not get expected TlsInsecureSkipVerify value from config file")
- }
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestLoadHttpConfigWithDefaultTimeouts(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileNoTimeouts.toml")
- if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileNoTimeouts), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- if assert.NoError(t, err, "Failed to load config file") {
- assert.False(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned true, when expecting false")
- assert.Equal(t, "https:localhost:9101", cfg.HttpUrl, "Did not get expected http url from config file")
- assert.Equal(t, DefaultConfig.Timeout, cfg.Timeout, "Did not get expected http Timeout from config file")
- assert.True(t, cfg.TlsInsecureSkipVerify, "Did not get expected TlsInsecureSkipVerify value from config file")
- }
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestHTTPTlsWithBlankRootCert(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileNoRootCert.toml")
- if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileNoRootCert), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestHTTPTlsMissingClientCerts(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "invalidHttpTlsConfigFileNoClientCert.toml")
- if err := ioutil.WriteFile(configFile, []byte(invalidHttpTlsConfigFileNoClientCert), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- assert.NoError(t, err)
- }
- func TestHTTPTlsMissingOnlyClientKey(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "invalidHttpTlsConfigFileOnlyClientCert.toml")
- if err := ioutil.WriteFile(configFile, []byte(invalidHttpTlsConfigFileOnlyClientCert), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "invalid details for HTTP connection with TLS, configuration must specify both clientCert and clientKey, or neither one")
- }
- }
- func TestHTTPTlsMissingOnlyClientCert(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "invalidHttpTlsConfigFileOnlyClientKey.toml")
- if err := ioutil.WriteFile(configFile, []byte(invalidHttpTlsConfigFileOnlyClientKey), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "invalid details for HTTP connection with TLS, configuration must specify both clientCert and clientKey, or neither one")
- }
- }
- func TestTlsWithHTTPUrlOnly(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileWithHTTPOnly.toml")
- if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileWithHTTPOnly), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "connection is configured with TLS but HTTPS url is not specified")
- }
- }
- func TestSocketWithHTTPNotAllowed(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "invalidConfigWithSocketAndHttp.toml")
- if err := ioutil.WriteFile(configFile, []byte(invalidConfigWithSocketAndHttp), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- cfg, err := FetchConfig(configFile)
- assert.NoError(t, err)
- err = cfg.Validate()
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "HTTP URL and unix ipc file cannot both be specified for private transaction manager connection")
- }
- }
- func TestEitherSocketOrHTTPMustBeSpecified(t *testing.T) {
- configFile := filepath.Join(os.TempDir(), "invalidConfigWithNoSocketOrHttp.toml")
- if err := ioutil.WriteFile(configFile, []byte(invalidConfigWithNoSocketOrHttp), 0600); err != nil {
- t.Fatalf("Failed to create config file for unit test, error: %v", err)
- }
- defer os.Remove(configFile)
- _, err := FetchConfig(configFile)
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "either Socket or HTTP connection must be specified in config file")
- }
- }
|