1// Copyright 2016 syzkaller project authors. All rights reserved.
2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4package config
5
6import (
7	"encoding/json"
8	"fmt"
9	"reflect"
10	"testing"
11	"time"
12)
13
14func TestLoad(t *testing.T) {
15	type NestedNested struct {
16		Ccc int
17		Ddd string
18	}
19	type Nested struct {
20		Aaa  int
21		Bbb  string
22		More NestedNested
23	}
24	type Config struct {
25		Foo int
26		Bar string
27		Baz string `json:"-"`
28		Raw json.RawMessage
29		Qux []string
30		Box Nested
31		Boq *Nested
32		Arr []Nested
33		T   time.Time
34	}
35
36	tests := []struct {
37		input  string
38		output Config
39		err    string
40	}{
41		{
42			`{"foo": 42}`,
43			Config{
44				Foo: 42,
45			},
46			"",
47		},
48		{
49			`{"BAR": "Baz", "foo": 42}`,
50			Config{
51				Foo: 42,
52				Bar: "Baz",
53			},
54			"",
55		},
56		{
57			`{"foobar": 42}`,
58			Config{},
59			"unknown field 'foobar' in config",
60		},
61		{
62			`{"foo": 1, "baz": "baz", "bar": "bar"}`,
63			Config{},
64			"unknown field 'baz' in config",
65		},
66		{
67			`{"foo": 1, "box": {"aaa": 12, "bbb": "bbb"}}`,
68			Config{
69				Foo: 1,
70				Box: Nested{
71					Aaa: 12,
72					Bbb: "bbb",
73				},
74			},
75			"",
76		},
77		{
78			`{"qux": ["aaa", "bbb"]}`,
79			Config{
80				Qux: []string{"aaa", "bbb"},
81			},
82			"",
83		},
84		{
85			`{"box": {"aaa": 12, "ccc": "bbb"}}`,
86			Config{},
87			"unknown field 'box.ccc' in config",
88		},
89		{
90			`{"foo": 1, "boq": {"aaa": 12, "bbb": "bbb"}}`,
91			Config{
92				Foo: 1,
93				Boq: &Nested{
94					Aaa: 12,
95					Bbb: "bbb",
96				},
97			},
98			"",
99		},
100		{
101			`{"boq": {"aaa": 12, "ccc": "bbb"}}`,
102			Config{},
103			"unknown field 'boq.ccc' in config",
104		},
105
106		{
107			`{"foo": 1, "arr": []}`,
108			Config{
109				Foo: 1,
110				Arr: []Nested{},
111			},
112			"",
113		},
114		{
115			`{"foo": 1, "arr": [{"aaa": 12, "bbb": "bbb"}, {"aaa": 13, "bbb": "ccc"}]}`,
116			Config{
117				Foo: 1,
118				Arr: []Nested{
119					{
120						Aaa: 12,
121						Bbb: "bbb",
122					},
123					{
124						Aaa: 13,
125						Bbb: "ccc",
126					},
127				},
128			},
129			"",
130		},
131		{
132			`{"arr": [{"aaa": 12, "ccc": "bbb"}]}`,
133			Config{},
134			"unknown field 'arr[0].ccc' in config",
135		},
136		{
137			`{"foo": 1, "boq": {"aaa": 12, "more": {"ccc": 13, "ddd": "ddd"}}}`,
138			Config{
139				Foo: 1,
140				Boq: &Nested{
141					Aaa: 12,
142					More: NestedNested{
143						Ccc: 13,
144						Ddd: "ddd",
145					},
146				},
147			},
148			"",
149		},
150		{
151			`{"foo": 1, "boq": {"aaa": 12, "more": {"ccc": 13, "eee": "eee"}}}`,
152			Config{},
153			"unknown field 'boq.more.eee' in config",
154		},
155		{
156			`{"raw": {"zux": 11}}`,
157			Config{
158				Raw: []byte(`{"zux": 11}`),
159			},
160			"",
161		},
162		{
163			`{"foo": null, "qux": null}`,
164			Config{},
165			"",
166		},
167		{
168			`{"t": "2000-01-02T03:04:05Z"}`,
169			Config{
170				T: time.Date(2000, 1, 2, 3, 4, 5, 0, time.UTC),
171			},
172			"",
173		},
174	}
175	for i, test := range tests {
176		t.Run(fmt.Sprint(i), func(t *testing.T) {
177			var cfg Config
178			err := LoadData([]byte(test.input), &cfg)
179			errStr := ""
180			if err != nil {
181				errStr = err.Error()
182			}
183			if test.err != errStr {
184				t.Fatalf("bad err: want '%v', got '%v'", test.err, errStr)
185			}
186			if !reflect.DeepEqual(test.output, cfg) {
187				t.Fatalf("bad output: want:\n%#v\n, got:\n%#v", test.output, cfg)
188			}
189		})
190	}
191}
192
193func TestLoadBadType(t *testing.T) {
194	want := "config type is not pointer to struct"
195	if err := LoadData([]byte("{}"), 1); err == nil || err.Error() != want {
196		t.Fatalf("got '%v', want '%v'", err, want)
197	}
198	i := 0
199	if err := LoadData([]byte("{}"), &i); err == nil || err.Error() != want {
200		t.Fatalf("got '%v', want '%v'", err, want)
201	}
202	s := struct{}{}
203	if err := LoadData([]byte("{}"), s); err == nil || err.Error() != want {
204		t.Fatalf("got '%v', want '%v'", err, want)
205	}
206}
207