11package config_test
22
33import (
4+ "encoding/json"
45 "time"
56
67 . "github.com/onsi/ginkgo/v2"
@@ -11,7 +12,11 @@ import (
1112)
1213
1314func dur (s string ) * cpi.Duration {
14- d := cpi .Duration (s )
15+ td , err := time .ParseDuration (s )
16+ if err != nil {
17+ panic (err )
18+ }
19+ d := cpi .Duration (td )
1520 return & d
1621}
1722
@@ -29,7 +34,7 @@ var _ = Describe("http config", func() {
2934
3035 Expect (cfg .ApplyTo (ctx .ConfigContext (), ctx )).To (Succeed ())
3136 g := MustGetHTTPSettings (ctx )
32- Expect (g .Timeout . TimeDuration ( )).To (HaveValue ( Equal (5 * time .Minute ) ))
37+ Expect (time . Duration ( * g .Timeout )).To (Equal (5 * time .Minute ))
3338 })
3439
3540 It ("applies via config context" , func () {
@@ -38,7 +43,7 @@ var _ = Describe("http config", func() {
3843
3944 Expect (ctx .ConfigContext ().ApplyConfig (cfg , "programmatic" )).To (Succeed ())
4045 g := MustGetHTTPSettings (ctx )
41- Expect (g .Timeout . TimeDuration ( )).To (HaveValue ( Equal (30 * time .Second ) ))
46+ Expect (time . Duration ( * g .Timeout )).To (Equal (30 * time .Second ))
4247 })
4348
4449 It ("parses all fields from JSON config" , func () {
@@ -49,12 +54,12 @@ var _ = Describe("http config", func() {
4954 Expect (ctx .ConfigContext ().ApplyConfig (cfg , "config file" )).To (Succeed ())
5055
5156 g := MustGetHTTPSettings (ctx )
52- Expect (g .Timeout . TimeDuration ( )).To (HaveValue ( Equal (10 * time .Second ) ))
53- Expect (g .TCPDialTimeout . TimeDuration ( )).To (HaveValue ( Equal (15 * time .Second ) ))
54- Expect (g .TCPKeepAlive . TimeDuration ( )).To (HaveValue ( Equal (20 * time .Second ) ))
55- Expect (g .TLSHandshakeTimeout . TimeDuration ( )).To (HaveValue ( Equal (5 * time .Second ) ))
56- Expect (g .ResponseHeaderTimeout . TimeDuration ( )).To (HaveValue ( Equal (8 * time .Second ) ))
57- Expect (g .IdleConnTimeout . TimeDuration ( )).To (HaveValue ( Equal (45 * time .Second ) ))
57+ Expect (time . Duration ( * g .Timeout )).To (Equal (10 * time .Second ))
58+ Expect (time . Duration ( * g .TCPDialTimeout )).To (Equal (15 * time .Second ))
59+ Expect (time . Duration ( * g .TCPKeepAlive )).To (Equal (20 * time .Second ))
60+ Expect (time . Duration ( * g .TLSHandshakeTimeout )).To (Equal (5 * time .Second ))
61+ Expect (time . Duration ( * g .ResponseHeaderTimeout )).To (Equal (8 * time .Second ))
62+ Expect (time . Duration ( * g .IdleConnTimeout )).To (Equal (45 * time .Second ))
5863 })
5964
6065 It ("successive ApplyConfig overrides only non-nil fields" , func () {
@@ -71,8 +76,8 @@ var _ = Describe("http config", func() {
7176 Expect (second .ApplyTo (ctx .ConfigContext (), ctx )).To (Succeed ())
7277
7378 g := MustGetHTTPSettings (ctx )
74- Expect (g .Timeout . TimeDuration ( )).To (HaveValue ( Equal (1 * time .Minute ) ))
75- Expect (g .TCPDialTimeout . TimeDuration ( )).To (HaveValue ( Equal (15 * time .Second ) ))
79+ Expect (time . Duration ( * g .Timeout )).To (Equal (1 * time .Minute ))
80+ Expect (time . Duration ( * g .TCPDialTimeout )).To (Equal (15 * time .Second ))
7681 })
7782
7883 It ("applies via generic config wrapper" , func () {
@@ -93,21 +98,27 @@ configurations:
9398 Expect (ctx .ConfigContext ().ApplyConfig (cfg , "config file" )).To (Succeed ())
9499
95100 g := MustGetHTTPSettings (ctx )
96- Expect (g .Timeout . TimeDuration ( )).To (HaveValue ( Equal (10 * time .Second ) ))
97- Expect (g .TCPDialTimeout . TimeDuration ( )).To (HaveValue ( Equal (15 * time .Second ) ))
98- Expect (g .TCPKeepAlive . TimeDuration ( )).To (HaveValue ( Equal (20 * time .Second ) ))
99- Expect (g .TLSHandshakeTimeout . TimeDuration ( )).To (HaveValue ( Equal (5 * time .Second ) ))
100- Expect (g .ResponseHeaderTimeout . TimeDuration ( )).To (HaveValue ( Equal (8 * time .Second ) ))
101- Expect (g .IdleConnTimeout . TimeDuration ( )).To (HaveValue ( Equal (45 * time .Second ) ))
101+ Expect (time . Duration ( * g .Timeout )).To (Equal (10 * time .Second ))
102+ Expect (time . Duration ( * g .TCPDialTimeout )).To (Equal (15 * time .Second ))
103+ Expect (time . Duration ( * g .TCPKeepAlive )).To (Equal (20 * time .Second ))
104+ Expect (time . Duration ( * g .TLSHandshakeTimeout )).To (Equal (5 * time .Second ))
105+ Expect (time . Duration ( * g .ResponseHeaderTimeout )).To (Equal (8 * time .Second ))
106+ Expect (time . Duration ( * g .IdleConnTimeout )).To (Equal (45 * time .Second ))
102107 })
103108
104- It ("rejects invalid duration string" , func () {
105- ctx := cpi .New ()
106- raw := []byte (`{"type":"http.config.ocm.software/v1alpha1","timeout":"notaduration"}` )
107- _ , err := ctx .ConfigContext ().GetConfigForData (raw , nil )
108- Expect (err ).To (HaveOccurred ())
109- Expect (err .Error ()).To (ContainSubstring ("invalid duration: notaduration" ))
110- })
109+ DescribeTable ("rejects invalid duration values on unmarshal" ,
110+ func (jsonValue string , expectedErr string ) {
111+ ctx := cpi .New ()
112+ raw := []byte (`{"type":"http.config.ocm.software/v1alpha1","timeout":` + jsonValue + `}` )
113+ _ , err := ctx .ConfigContext ().GetConfigForData (raw , nil )
114+ Expect (err ).To (HaveOccurred ())
115+ Expect (err .Error ()).To (ContainSubstring (expectedErr ))
116+ },
117+ Entry ("garbage string" , `"notaduration"` , "expected a Go duration string" ),
118+ Entry ("number instead of string" , `42` , "expected a Go duration string" ),
119+ Entry ("boolean instead of string" , `true` , "expected a Go duration string" ),
120+ Entry ("empty string" , `""` , "expected a Go duration string" ),
121+ )
111122
112123 DescribeTable ("rejects negative duration for timeout fields" ,
113124 func (field string , cfg * config.HTTPConfig ) {
@@ -116,24 +127,24 @@ configurations:
116127 ContainSubstring ("invalid value for " + field ),
117128 ))
118129 },
119- Entry ("timeout" , "timeout" ,
130+ Entry ("timeout -5m " , "timeout" ,
120131 & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {Timeout : dur ("-5m" )}}),
121- Entry ("tcpDialTimeout" , "tcpDialTimeout" ,
122- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TCPDialTimeout : dur ("-5m " )}}),
123- Entry ("tlsHandshakeTimeout" , "tlsHandshakeTimeout" ,
124- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TLSHandshakeTimeout : dur ("-5m " )}}),
125- Entry ("responseHeaderTimeout" , "responseHeaderTimeout" ,
126- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {ResponseHeaderTimeout : dur ("-5m " )}}),
127- Entry ("idleConnTimeout" , "idleConnTimeout" ,
128- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {IdleConnTimeout : dur ("-5m " )}}),
132+ Entry ("tcpDialTimeout -10s " , "tcpDialTimeout" ,
133+ & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TCPDialTimeout : dur ("-10s " )}}),
134+ Entry ("tlsHandshakeTimeout -10h5m " , "tlsHandshakeTimeout" ,
135+ & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TLSHandshakeTimeout : dur ("-10h5m " )}}),
136+ Entry ("responseHeaderTimeout -1s " , "responseHeaderTimeout" ,
137+ & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {ResponseHeaderTimeout : dur ("-1s " )}}),
138+ Entry ("idleConnTimeout -30s " , "idleConnTimeout" ,
139+ & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {IdleConnTimeout : dur ("-30s " )}}),
129140 )
130141
131142 It ("allows negative tcpKeepAlive to disable keep-alive probes" , func () {
132143 ctx := cpi .New ()
133144 cfg := & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TCPKeepAlive : dur ("-1s" )}}
134145 Expect (cfg .ApplyTo (ctx .ConfigContext (), ctx )).To (Succeed ())
135146 g := MustGetHTTPSettings (ctx )
136- Expect (g .TCPKeepAlive . TimeDuration ( )).To (HaveValue ( Equal (- 1 * time .Second ) ))
147+ Expect (time . Duration ( * g .TCPKeepAlive )).To (Equal (- 1 * time .Second ))
137148 })
138149
139150 DescribeTable ("accepts compound duration like 1h5s" ,
@@ -149,44 +160,6 @@ configurations:
149160 Entry ("idleConnTimeout" , & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {IdleConnTimeout : dur ("1h5s" )}}),
150161 )
151162
152- DescribeTable ("rejects negative compound duration -10h5m" ,
153- func (field string , cfg * config.HTTPConfig ) {
154- ctx := cpi .New ()
155- Expect (cfg .ApplyTo (ctx .ConfigContext (), ctx )).To (MatchError (
156- ContainSubstring ("invalid value for " + field ),
157- ))
158- },
159- Entry ("timeout" , "timeout" ,
160- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {Timeout : dur ("-10h5m" )}}),
161- Entry ("tcpDialTimeout" , "tcpDialTimeout" ,
162- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TCPDialTimeout : dur ("-10h5m" )}}),
163- Entry ("tlsHandshakeTimeout" , "tlsHandshakeTimeout" ,
164- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TLSHandshakeTimeout : dur ("-10h5m" )}}),
165- Entry ("responseHeaderTimeout" , "responseHeaderTimeout" ,
166- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {ResponseHeaderTimeout : dur ("-10h5m" )}}),
167- Entry ("idleConnTimeout" , "idleConnTimeout" ,
168- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {IdleConnTimeout : dur ("-10h5m" )}}),
169- )
170-
171- DescribeTable ("rejects -10s" ,
172- func (field string , cfg * config.HTTPConfig ) {
173- ctx := cpi .New ()
174- Expect (cfg .ApplyTo (ctx .ConfigContext (), ctx )).To (MatchError (
175- ContainSubstring ("invalid value for " + field ),
176- ))
177- },
178- Entry ("timeout" , "timeout" ,
179- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {Timeout : dur ("-10s" )}}),
180- Entry ("tcpDialTimeout" , "tcpDialTimeout" ,
181- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TCPDialTimeout : dur ("-10s" )}}),
182- Entry ("tlsHandshakeTimeout" , "tlsHandshakeTimeout" ,
183- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {TLSHandshakeTimeout : dur ("-10s" )}}),
184- Entry ("responseHeaderTimeout" , "responseHeaderTimeout" ,
185- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {ResponseHeaderTimeout : dur ("-10s" )}}),
186- Entry ("idleConnTimeout" , "idleConnTimeout" ,
187- & config.HTTPConfig {HTTPSettings : cpi.HTTPSettings {IdleConnTimeout : dur ("-10s" )}}),
188- )
189-
190163 It ("default settings are nil" , func () {
191164 g := MustGetHTTPSettings (cpi .New ())
192165 Expect (g .Timeout ).To (BeNil ())
@@ -199,9 +172,22 @@ configurations:
199172
200173 It ("nil timeout returns nil not zero" , func () {
201174 g := MustGetHTTPSettings (cpi .New ())
202- timeout , err := g .Timeout .TimeDuration ()
175+ Expect (g .Timeout ).To (BeNil ())
176+ })
177+
178+ It ("round-trips Duration through MarshalJSON and UnmarshalJSON" , func () {
179+ original := cpi.HTTPSettings {
180+ Timeout : dur ("5m30s" ),
181+ TCPDialTimeout : dur ("15s" ),
182+ }
183+ data , err := json .Marshal (original )
203184 Expect (err ).To (Succeed ())
204- Expect (timeout ).To (BeNil ())
185+
186+ var restored cpi.HTTPSettings
187+ Expect (json .Unmarshal (data , & restored )).To (Succeed ())
188+ Expect (time .Duration (* restored .Timeout )).To (Equal (5 * time .Minute + 30 * time .Second ))
189+ Expect (time .Duration (* restored .TCPDialTimeout )).To (Equal (15 * time .Second ))
190+ Expect (restored .TCPKeepAlive ).To (BeNil ())
205191 })
206192 })
207193})
0 commit comments