Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata TryGetTTL: adds time.ParseDuration support #3122

Merged
merged 9 commits into from
Jan 16, 2024
25 changes: 15 additions & 10 deletions metadata/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,24 @@ const (
// TryGetTTL tries to get the ttl as a time.Duration value for pubsub, binding and any other building block.
func TryGetTTL(props map[string]string) (time.Duration, bool, error) {
if val, ok := props[TTLMetadataKey]; ok && val != "" {
ItalyPaleAle marked this conversation as resolved.
Show resolved Hide resolved
valInt64, err := strconv.ParseInt(val, 10, 64)
duration, err := time.ParseDuration(val)
ItalyPaleAle marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return 0, false, fmt.Errorf("%s value must be a valid integer: actual is '%s'", TTLMetadataKey, val)
}
// failed to parse Duration string.
// let's try Integer and assume the value is in seconds
valInt64, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return 0, false, fmt.Errorf("%s value must be a valid integer: actual is '%s'", TTLMetadataKey, val)
ItalyPaleAle marked this conversation as resolved.
Show resolved Hide resolved
}

if valInt64 <= 0 {
return 0, false, fmt.Errorf("%s value must be higher than zero: actual is %d", TTLMetadataKey, valInt64)
}
if valInt64 <= 0 {
return 0, false, fmt.Errorf("%s value must be higher than zero: actual is %d", TTLMetadataKey, valInt64)
}

duration := time.Duration(valInt64) * time.Second
if duration < 0 {
// Overflow
duration = math.MaxInt64
duration = time.Duration(valInt64) * time.Second
if duration < 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to outside of the if err != nil { block. Because the duration parsed by time.ParseDuration could be < 0 too

// Overflow
duration = math.MaxInt64
}
}

return duration, true, nil
Expand Down
79 changes: 79 additions & 0 deletions metadata/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ limitations under the License.
package metadata

import (
"fmt"
"math"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -513,3 +515,80 @@ func TestResolveAliases(t *testing.T) {
})
}
}

func TestTryGetTTL(t *testing.T) {
tests := []struct {
name string
md map[string]string
result any
wantOK bool
wantErr bool
errStr string
}{
{
name: "valid duration 20s",
ItalyPaleAle marked this conversation as resolved.
Show resolved Hide resolved
md: map[string]string{
TTLMetadataKey: "20s",
},
result: time.Duration(20) * time.Second,
wantOK: true,
},
{
name: "valid integer 20",
md: map[string]string{
TTLMetadataKey: "20",
},
result: time.Duration(20) * time.Second,
wantOK: true,
},
{
name: "invalid integer 20b",
md: map[string]string{
TTLMetadataKey: "20b",
},
wantOK: false,
wantErr: true,
errStr: "ttlInSeconds value must be a valid integer: actual is '20b'",
result: time.Duration(0) * time.Second,
},
{
name: "negative ttlInSeconds -1",
md: map[string]string{
TTLMetadataKey: "-1",
},
wantOK: false,
wantErr: true,
errStr: "ttlInSeconds value must be higher than zero: actual is -1",
result: time.Duration(0) * time.Second,
},
{
name: "no ttlInSeconds",
md: map[string]string{},
wantOK: false,
wantErr: false,
result: time.Duration(0) * time.Second,
},
{
name: "out of range",
md: map[string]string{
TTLMetadataKey: fmt.Sprintf("%d1", math.MaxInt64),
},
wantOK: false,
wantErr: true,
result: time.Duration(0) * time.Second,
errStr: "ttlInSeconds value must be a valid integer: actual is '92233720368547758071'",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d, ok, err := TryGetTTL(tt.md)

if tt.wantErr {
assert.Error(t, err)
assert.EqualError(t, err, tt.errStr)
}
assert.Equal(t, tt.wantOK, ok, "wanted ok, but instead got not ok")
assert.Equal(t, tt.result, d, "expected result %v, but instead got = %v", tt.result, d)
})
}
}