package pogs import ( "encoding/json" "strings" "testing" "time" "github.com/stretchr/testify/assert" ) func TestUnmarshalOrigin(t *testing.T) { tests := []struct { jsonLiteral string exceptedOriginConfig OriginConfig }{ { jsonLiteral: `{ "Http":{ "url_string":"https.example.com", "tcp_keep_alive":7000000000, "dial_dual_stack":true, "tls_handshake_timeout":11000000000, "tls_verify":true, "origin_ca_pool":"/etc/cert.pem", "origin_server_name":"secure.example.com", "max_idle_connections":19, "idle_connection_timeout":17000000000, "proxy_connection_timeout":15000000000, "expect_continue_timeout":21000000000, "chunked_encoding":true } }`, exceptedOriginConfig: sampleHTTPOriginConfig(), }, { jsonLiteral: `{ "WebSocket":{ "url_string":"ssh://example.com", "tls_verify":true, "origin_ca_pool":"/etc/cert.pem", "origin_server_name":"secure.example.com" } }`, exceptedOriginConfig: sampleWebSocketOriginConfig(), }, { jsonLiteral: `{ "HelloWorld": {} }`, exceptedOriginConfig: &HelloWorldOriginConfig{}, }, } for _, test := range tests { originConfigJSON := prettyToValidJSON(test.jsonLiteral) var OriginConfigJSONHandler OriginConfigJSONHandler err := json.Unmarshal([]byte(originConfigJSON), &OriginConfigJSONHandler) assert.NoError(t, err) assert.Equal(t, test.exceptedOriginConfig, OriginConfigJSONHandler.OriginConfig) } } func TestUnmarshalClientConfig(t *testing.T) { prettyClientConfigJSON := `{ "version":10, "supervisor_config":{ "auto_update_frequency":86400000000000, "metrics_update_frequency":300000000000, "grace_period":30000000000 }, "edge_connection_config":{ "num_ha_connections":4, "heartbeat_interval":5000000000, "timeout":30000000000, "max_failed_heartbeats":5, "user_credential_path":"~/.cloudflared/cert.pem" }, "doh_proxy_configs":[{ "listen_host": "localhost", "listen_port": 53, "upstreams": ["https://1.1.1.1/dns-query", "https://1.0.0.1/dns-query"] }], "reverse_proxy_configs":[{ "tunnel_hostname":"sdfjadk33.cftunnel.com", "origin_config":{ "Http":{ "url_string":"https://127.0.0.1:8080", "tcp_keep_alive":30000000000, "dial_dual_stack":true, "tls_handshake_timeout":10000000000, "tls_verify":true, "origin_ca_pool":"", "origin_server_name":"", "max_idle_connections":100, "idle_connection_timeout":90000000000, "proxy_connection_timeout":90000000000, "expect_continue_timeout":90000000000, "chunked_encoding":true } }, "retries":5, "connection_timeout":30, "compression_quality":0 }] }` // replace new line and tab clientConfigJSON := prettyToValidJSON(prettyClientConfigJSON) var clientConfig ClientConfig err := json.Unmarshal([]byte(clientConfigJSON), &clientConfig) assert.NoError(t, err) assert.Equal(t, Version(10), clientConfig.Version) supervisorConfig := SupervisorConfig{ AutoUpdateFrequency: time.Hour * 24, MetricsUpdateFrequency: time.Second * 300, GracePeriod: time.Second * 30, } assert.Equal(t, supervisorConfig, *clientConfig.SupervisorConfig) edgeConnectionConfig := EdgeConnectionConfig{ NumHAConnections: 4, HeartbeatInterval: time.Second * 5, Timeout: time.Second * 30, MaxFailedHeartbeats: 5, UserCredentialPath: "~/.cloudflared/cert.pem", } assert.Equal(t, edgeConnectionConfig, *clientConfig.EdgeConnectionConfig) dohProxyConfig := DoHProxyConfig{ ListenHost: "localhost", ListenPort: 53, Upstreams: []string{"https://1.1.1.1/dns-query", "https://1.0.0.1/dns-query"}, } assert.Len(t, clientConfig.DoHProxyConfigs, 1) assert.Equal(t, dohProxyConfig, *clientConfig.DoHProxyConfigs[0]) reverseProxyConfig := ReverseProxyConfig{ TunnelHostname: "sdfjadk33.cftunnel.com", OriginConfigJSONHandler: &OriginConfigJSONHandler{ OriginConfig: &HTTPOriginConfig{ URLString: "https://127.0.0.1:8080", TCPKeepAlive: time.Second * 30, DialDualStack: true, TLSHandshakeTimeout: time.Second * 10, TLSVerify: true, OriginCAPool: "", OriginServerName: "", MaxIdleConnections: 100, IdleConnectionTimeout: time.Second * 90, ProxyConnectionTimeout: time.Second * 90, ExpectContinueTimeout: time.Second * 90, ChunkedEncoding: true, }, }, Retries: 5, ConnectionTimeout: 30, CompressionQuality: 0, } assert.Len(t, clientConfig.ReverseProxyConfigs, 1) assert.Equal(t, reverseProxyConfig, *clientConfig.ReverseProxyConfigs[0]) } func TestMarshalFallibleConfig(t *testing.T) { tests := []struct { fallibleConfig FallibleConfig expctedJSONLiteral string }{ { fallibleConfig: sampleSupervisorConfig(), expctedJSONLiteral: `{ "supervisor_config":{ "auto_update_frequency":75600000000000, "metrics_update_frequency":660000000000, "grace_period":31000000000 } }`, }, { fallibleConfig: sampleEdgeConnectionConfig(), expctedJSONLiteral: `{ "edge_connection_config":{ "num_ha_connections":49, "heartbeat_interval":5000000000, "timeout":9000000000, "max_failed_heartbeats":9001, "user_credential_path":"/Users/example/.cloudflared/cert.pem" } }`, }, { fallibleConfig: sampleDoHProxyConfig(), expctedJSONLiteral: `{ "doh_proxy_config":{ "listen_host":"127.0.0.1", "listen_port":53, "upstreams":["1.1.1.1","1.0.0.1"] } }`, }, { fallibleConfig: sampleReverseProxyConfig(func(c *ReverseProxyConfig) { c.OriginConfigJSONHandler = &OriginConfigJSONHandler{sampleHTTPOriginConfig()} }), expctedJSONLiteral: `{ "reverse_proxy_config":{ "tunnel_hostname":"mock-non-lb-tunnel.example.com", "origin_config":{ "Http":{ "url_string":"https.example.com", "tcp_keep_alive":7000000000, "dial_dual_stack":true, "tls_handshake_timeout":11000000000, "tls_verify":true, "origin_ca_pool":"/etc/cert.pem", "origin_server_name":"secure.example.com", "max_idle_connections":19, "idle_connection_timeout":17000000000, "proxy_connection_timeout":15000000000, "expect_continue_timeout":21000000000, "chunked_encoding":true } }, "retries":18, "connection_timeout":5000000000, "compression_quality":3 } }`, }, { fallibleConfig: sampleReverseProxyConfig(func(c *ReverseProxyConfig) { c.OriginConfigJSONHandler = &OriginConfigJSONHandler{sampleWebSocketOriginConfig()} }), expctedJSONLiteral: `{ "reverse_proxy_config":{ "tunnel_hostname":"mock-non-lb-tunnel.example.com", "origin_config":{ "WebSocket":{ "url_string":"ssh://example.com", "tls_verify":true, "origin_ca_pool":"/etc/cert.pem", "origin_server_name":"secure.example.com" } }, "retries":18, "connection_timeout":5000000000, "compression_quality":3 } }`, }, { fallibleConfig: sampleReverseProxyConfig(func(c *ReverseProxyConfig) { c.OriginConfigJSONHandler = &OriginConfigJSONHandler{&HelloWorldOriginConfig{}} }), expctedJSONLiteral: `{ "reverse_proxy_config":{ "tunnel_hostname":"mock-non-lb-tunnel.example.com", "origin_config":{ "HelloWorld":{} }, "retries":18, "connection_timeout":5000000000, "compression_quality":3 } }`, }, } for _, test := range tests { b, err := json.Marshal(test.fallibleConfig) assert.NoError(t, err) assert.Equal(t, prettyToValidJSON(test.expctedJSONLiteral), string(b)) } } type prettyJSON string func prettyToValidJSON(prettyJSON string) string { return strings.ReplaceAll(strings.ReplaceAll(prettyJSON, "\n", ""), "\t", "") }