Skip to content

Commit 5e1598b

Browse files
authored
feat: Add JSON schema for configtype.Duration (#1303)
1 parent cea6a6c commit 5e1598b

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

configtype/duration.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package configtype
33
import (
44
"encoding/json"
55
"time"
6+
7+
"github.com/invopop/jsonschema"
68
)
79

810
// Duration is a wrapper around time.Duration that should be used in config
@@ -19,6 +21,14 @@ func NewDuration(d time.Duration) Duration {
1921
}
2022
}
2123

24+
func (Duration) JSONSchema() *jsonschema.Schema {
25+
return &jsonschema.Schema{
26+
Type: "string",
27+
Pattern: `^[-+]?([0-9]*(\.[0-9]*)?[a-z]+)+$`, // copied from time.ParseDuration
28+
Title: "CloudQuery configtype.Duration",
29+
}
30+
}
31+
2232
func (d *Duration) UnmarshalJSON(b []byte) error {
2333
var s string
2434
if err := json.Unmarshal(b, &s); err != nil {

configtype/duration_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ package configtype_test
22

33
import (
44
"encoding/json"
5+
"math/rand"
56
"testing"
67
"time"
78

89
"github.com/cloudquery/plugin-sdk/v4/configtype"
10+
"github.com/cloudquery/plugin-sdk/v4/plugin"
911
"github.com/google/go-cmp/cmp"
12+
"github.com/invopop/jsonschema"
13+
"github.com/stretchr/testify/require"
1014
)
1115

1216
func TestDuration(t *testing.T) {
@@ -52,3 +56,74 @@ func TestComparability(t *testing.T) {
5256
}
5357
}
5458
}
59+
60+
func TestDuration_JSONSchema(t *testing.T) {
61+
sc := (&jsonschema.Reflector{RequiredFromJSONSchemaTags: true}).Reflect(configtype.Duration{})
62+
schema, err := json.MarshalIndent(sc, "", " ")
63+
require.NoError(t, err)
64+
65+
validator, err := plugin.JSONSchemaValidator(string(schema))
66+
require.NoError(t, err)
67+
68+
type testCase struct {
69+
Name string
70+
Spec string
71+
Err bool
72+
}
73+
74+
for _, tc := range append([]testCase{
75+
{
76+
Name: "empty",
77+
Err: true,
78+
Spec: `""`,
79+
},
80+
{
81+
Name: "null",
82+
Err: true,
83+
Spec: `null`,
84+
},
85+
{
86+
Name: "bad type",
87+
Err: true,
88+
Spec: `false`,
89+
},
90+
{
91+
Name: "bad format",
92+
Err: true,
93+
Spec: `false`,
94+
},
95+
},
96+
func() []testCase {
97+
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
98+
const (
99+
cases = 20
100+
maxDur = int64(100 * time.Hour)
101+
maxDurHalf = maxDur / 2
102+
)
103+
result := make([]testCase, cases)
104+
for i := 0; i < cases; i++ {
105+
val := rnd.Int63n(maxDur) - maxDurHalf
106+
d := configtype.NewDuration(time.Duration(val))
107+
108+
data, err := d.MarshalJSON()
109+
require.NoError(t, err)
110+
result[i] = testCase{
111+
Name: string(data),
112+
Spec: string(data),
113+
}
114+
}
115+
return result
116+
}()...,
117+
) {
118+
t.Run(tc.Name, func(t *testing.T) {
119+
var val any
120+
err := json.Unmarshal([]byte(tc.Spec), &val)
121+
require.NoError(t, err)
122+
if tc.Err {
123+
require.Error(t, validator.Validate(val))
124+
} else {
125+
require.NoError(t, validator.Validate(val))
126+
}
127+
})
128+
}
129+
}

scheduler/strategy_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package scheduler_test
33
import (
44
_ "embed"
55
"encoding/json"
6-
"reflect"
76
"testing"
87

98
"github.com/cloudquery/plugin-sdk/v4/plugin"
@@ -13,7 +12,7 @@ import (
1312
)
1413

1514
func TestStrategy_JSONSchema(t *testing.T) {
16-
sc := (&jsonschema.Reflector{RequiredFromJSONSchemaTags: true}).ReflectFromType(reflect.TypeOf(scheduler.StrategyDFS))
15+
sc := (&jsonschema.Reflector{RequiredFromJSONSchemaTags: true}).Reflect(scheduler.StrategyDFS)
1716
schema, err := json.MarshalIndent(sc, "", " ")
1817
require.NoError(t, err)
1918

0 commit comments

Comments
 (0)