xref: /aosp_15_r20/build/blueprint/proptools/hash_provider_test.go (revision 1fa6dee971e1612fa5cc0aa5ca2d35a22e2c34a3)
1package proptools
2
3import (
4	"strings"
5	"testing"
6)
7
8func mustHash(t *testing.T, data interface{}) uint64 {
9	t.Helper()
10	result, err := CalculateHash(data)
11	if err != nil {
12		t.Fatal(err)
13	}
14	return result
15}
16
17func TestHashingMapGetsSameResults(t *testing.T) {
18	data := map[string]string{"foo": "bar", "baz": "qux"}
19	first := mustHash(t, data)
20	second := mustHash(t, data)
21	third := mustHash(t, data)
22	fourth := mustHash(t, data)
23	if first != second || second != third || third != fourth {
24		t.Fatal("Did not get the same result every time for a map")
25	}
26}
27
28func TestHashingNonSerializableTypesFails(t *testing.T) {
29	testCases := []struct {
30		name string
31		data interface{}
32	}{
33		{
34			name: "function pointer",
35			data: []func(){nil},
36		},
37		{
38			name: "channel",
39			data: []chan int{make(chan int)},
40		},
41		{
42			name: "list with non-serializable type",
43			data: []interface{}{"foo", make(chan int)},
44		},
45	}
46	for _, testCase := range testCases {
47		t.Run(testCase.name, func(t *testing.T) {
48			_, err := CalculateHash(testCase)
49			if err == nil {
50				t.Fatal("Expected hashing error but didn't get one")
51			}
52			expected := "data may only contain primitives, strings, arrays, slices, structs, maps, and pointers"
53			if !strings.Contains(err.Error(), expected) {
54				t.Fatalf("Expected %q, got %q", expected, err.Error())
55			}
56		})
57	}
58}
59
60func TestHashSuccessful(t *testing.T) {
61	testCases := []struct {
62		name string
63		data interface{}
64	}{
65		{
66			name: "int",
67			data: 5,
68		},
69		{
70			name: "string",
71			data: "foo",
72		},
73		{
74			name: "*string",
75			data: StringPtr("foo"),
76		},
77		{
78			name: "array",
79			data: [3]string{"foo", "bar", "baz"},
80		},
81		{
82			name: "slice",
83			data: []string{"foo", "bar", "baz"},
84		},
85		{
86			name: "struct",
87			data: struct {
88				foo string
89				bar int
90			}{
91				foo: "foo",
92				bar: 3,
93			},
94		},
95		{
96			name: "map",
97			data: map[string]int{
98				"foo": 3,
99				"bar": 4,
100			},
101		},
102		{
103			name: "list of interfaces with different types",
104			data: []interface{}{"foo", 3, []string{"bar", "baz"}},
105		},
106	}
107	for _, testCase := range testCases {
108		t.Run(testCase.name, func(t *testing.T) {
109			mustHash(t, testCase.data)
110		})
111	}
112}
113
114func TestHashingDereferencePointers(t *testing.T) {
115	str1 := "this is a hash test for pointers"
116	str2 := "this is a hash test for pointers"
117	data := []struct {
118		content *string
119	}{
120		{content: &str1},
121		{content: &str2},
122	}
123	first := mustHash(t, data[0])
124	second := mustHash(t, data[1])
125	if first != second {
126		t.Fatal("Got different results for the same string")
127	}
128}
129