@@ -25,8 +25,12 @@ import (
25
25
"github.com/stretchr/testify/require"
26
26
"google.golang.org/protobuf/types/known/wrapperspb"
27
27
28
+ cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
28
29
endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
30
+ discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
29
31
"github.com/envoyproxy/go-control-plane/pkg/cache/types"
32
+ "github.com/envoyproxy/go-control-plane/pkg/log"
33
+ "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
30
34
"github.com/envoyproxy/go-control-plane/pkg/server/stream/v3"
31
35
)
32
36
@@ -38,18 +42,18 @@ func testResource(s string) types.Resource {
38
42
return wrapperspb .String (s )
39
43
}
40
44
41
- func verifyResponse (t * testing.T , ch <- chan Response , version string , num int ) {
45
+ func verifyResponseContent (t * testing.T , ch <- chan Response , expectedType string , expectedVersion string ) ( Response , * discovery. DiscoveryResponse ) {
42
46
t .Helper ()
43
47
var r Response
44
48
select {
45
49
case r = <- ch :
46
50
case <- time .After (1 * time .Second ):
47
51
t .Error ("failed to receive response after 1 second" )
48
- return
52
+ return nil , nil
49
53
}
50
54
51
- if r .GetRequest ().GetTypeUrl () != testType {
52
- t .Errorf ("unexpected empty request type URL: %q" , r .GetRequest ().GetTypeUrl ())
55
+ if r .GetRequest ().GetTypeUrl () != expectedType {
56
+ t .Errorf ("unexpected request type URL: %q" , r .GetRequest ().GetTypeUrl ())
53
57
}
54
58
if r .GetContext () == nil {
55
59
t .Errorf ("unexpected empty response context" )
@@ -61,18 +65,41 @@ func verifyResponse(t *testing.T, ch <-chan Response, version string, num int) {
61
65
if out .GetVersionInfo () == "" {
62
66
t .Error ("unexpected response empty version" )
63
67
}
64
- if n := len (out .GetResources ()); n != num {
65
- t .Errorf ("unexpected number of responses: got %d, want %d" , n , num )
66
- }
67
- if version != "" && out .GetVersionInfo () != version {
68
- t .Errorf ("unexpected version: got %q, want %q" , out .GetVersionInfo (), version )
68
+ if expectedVersion != "" && out .GetVersionInfo () != expectedVersion {
69
+ t .Errorf ("unexpected version: got %q, want %q" , out .GetVersionInfo (), expectedVersion )
69
70
}
70
- if out .GetTypeUrl () != testType {
71
+ if out .GetTypeUrl () != expectedType {
71
72
t .Errorf ("unexpected type URL: %q" , out .GetTypeUrl ())
72
73
}
73
74
if len (r .GetRequest ().GetResourceNames ()) != 0 && len (r .GetRequest ().GetResourceNames ()) < len (out .Resources ) {
74
75
t .Errorf ("received more resources (%d) than requested (%d)" , len (r .GetRequest ().GetResourceNames ()), len (out .Resources ))
75
76
}
77
+ return r , out
78
+ }
79
+
80
+ func verifyResponse (t * testing.T , ch <- chan Response , expectedVersion string , expectedResourcesNb int ) {
81
+ t .Helper ()
82
+ _ , r := verifyResponseContent (t , ch , testType , expectedVersion )
83
+ if r == nil {
84
+ return
85
+ }
86
+ if n := len (r .GetResources ()); n != expectedResourcesNb {
87
+ t .Errorf ("unexpected number of responses: got %d, want %d" , n , expectedResourcesNb )
88
+ }
89
+ }
90
+
91
+ func verifyResponseResources (t * testing.T , ch <- chan Response , expectedType string , expectedVersion string , expectedResources ... string ) {
92
+ t .Helper ()
93
+ r , _ := verifyResponseContent (t , ch , expectedType , expectedVersion )
94
+ if r == nil {
95
+ return
96
+ }
97
+ out := r .(* RawResponse )
98
+ resourceNames := []string {}
99
+ for _ , res := range out .Resources {
100
+ resourceNames = append (resourceNames , GetResourceName (res .Resource ))
101
+ }
102
+ assert .ElementsMatch (t , resourceNames , expectedResources )
76
103
}
77
104
78
105
type resourceInfo struct {
@@ -172,6 +199,7 @@ func checkVersionMapSet(t *testing.T, c *LinearCache) {
172
199
}
173
200
174
201
func mustBlock (t * testing.T , w <- chan Response ) {
202
+ t .Helper ()
175
203
select {
176
204
case <- w :
177
205
t .Error ("watch must block" )
@@ -180,6 +208,7 @@ func mustBlock(t *testing.T, w <-chan Response) {
180
208
}
181
209
182
210
func mustBlockDelta (t * testing.T , w <- chan DeltaResponse ) {
211
+ t .Helper ()
183
212
select {
184
213
case <- w :
185
214
t .Error ("watch must block" )
@@ -188,6 +217,7 @@ func mustBlockDelta(t *testing.T, w <-chan DeltaResponse) {
188
217
}
189
218
190
219
func hashResource (t * testing.T , resource types.Resource ) string {
220
+ t .Helper ()
191
221
marshaledResource , err := MarshalResource (resource )
192
222
if err != nil {
193
223
t .Fatal (err )
@@ -815,7 +845,7 @@ func TestLinearSotwWatches(t *testing.T) {
815
845
}}
816
846
err = cache .UpdateResources (map [string ]types.Resource {"a" : a }, nil )
817
847
require .NoError (t , err )
818
- verifyResponse (t , w , cache .getVersion (), 1 )
848
+ verifyResponseResources (t , w , testType , cache .getVersion (), "a" )
819
849
checkVersionMapNotSet (t , cache )
820
850
821
851
assert .Empty (t , cache .watches ["a" ])
@@ -839,7 +869,7 @@ func TestLinearSotwWatches(t *testing.T) {
839
869
assert .Empty (t , cache .watches ["c" ])
840
870
841
871
require .NoError (t , err )
842
- verifyResponse (t , w , cache .getVersion (), 1 )
872
+ verifyResponseResources (t , w , testType , cache .getVersion (), "b" )
843
873
checkVersionMapNotSet (t , cache )
844
874
845
875
w = make (chan Response , 1 )
@@ -853,11 +883,72 @@ func TestLinearSotwWatches(t *testing.T) {
853
883
}}
854
884
err = cache .UpdateResources (map [string ]types.Resource {"c" : c }, nil )
855
885
require .NoError (t , err )
856
- verifyResponse (t , w , cache .getVersion (), 1 )
886
+ verifyResponseResources (t , w , testType , cache .getVersion (), "c" )
857
887
checkVersionMapNotSet (t , cache )
858
888
859
889
assert .Empty (t , cache .watches ["a" ])
860
890
assert .Empty (t , cache .watches ["b" ])
861
891
assert .Empty (t , cache .watches ["c" ])
862
892
})
893
+
894
+ t .Run ("watches return full state for types requesting it" , func (t * testing.T ) {
895
+ a := & cluster.Cluster {Name : "a" }
896
+ b := & cluster.Cluster {Name : "b" }
897
+ c := & cluster.Cluster {Name : "c" }
898
+ // ClusterType requires all resources to always be returned
899
+ cache := NewLinearCache (resource .ClusterType , WithInitialResources (map [string ]types.Resource {
900
+ "a" : a ,
901
+ "b" : b ,
902
+ "c" : c ,
903
+ }), WithLogger (log .NewTestLogger (t )))
904
+ assert .Equal (t , 3 , cache .NumResources ())
905
+
906
+ // Non-wildcard request
907
+ nonWildcardState := stream .NewStreamState (false , nil )
908
+ w1 := make (chan Response , 1 )
909
+ _ = cache .CreateWatch (& Request {ResourceNames : []string {"a" , "b" , "d" }, TypeUrl : resource .ClusterType , VersionInfo : cache .getVersion ()}, nonWildcardState , w1 )
910
+ mustBlock (t , w1 )
911
+ checkVersionMapNotSet (t , cache )
912
+
913
+ // wildcard request
914
+ wildcardState := stream .NewStreamState (true , nil )
915
+ w2 := make (chan Response , 1 )
916
+ _ = cache .CreateWatch (& Request {ResourceNames : nil , TypeUrl : resource .ClusterType , VersionInfo : cache .getVersion ()}, wildcardState , w2 )
917
+ mustBlock (t , w2 )
918
+ checkVersionMapNotSet (t , cache )
919
+
920
+ // request not requesting b
921
+ otherState := stream .NewStreamState (false , nil )
922
+ w3 := make (chan Response , 1 )
923
+ _ = cache .CreateWatch (& Request {ResourceNames : []string {"a" , "c" , "d" }, TypeUrl : resource .ClusterType , VersionInfo : cache .getVersion ()}, otherState , w3 )
924
+ mustBlock (t , w3 )
925
+ checkVersionMapNotSet (t , cache )
926
+
927
+ b .AltStatName = "othername"
928
+ err := cache .UpdateResources (map [string ]types.Resource {"b" : b }, nil )
929
+ require .NoError (t , err )
930
+
931
+ // Other watch has not triggered
932
+ mustBlock (t , w3 )
933
+
934
+ verifyResponseResources (t , w1 , resource .ClusterType , cache .getVersion (), "a" , "b" ) // a is also returned as cluster requires full state
935
+ verifyResponseResources (t , w2 , resource .ClusterType , cache .getVersion (), "a" , "b" , "c" ) // a and c are also returned wildcard
936
+
937
+ // Recreate the watches
938
+ w1 = make (chan Response , 1 )
939
+ _ = cache .CreateWatch (& Request {ResourceNames : []string {"a" , "b" , "d" }, TypeUrl : resource .ClusterType , VersionInfo : cache .getVersion ()}, nonWildcardState , w1 )
940
+ mustBlock (t , w1 )
941
+ w2 = make (chan Response , 1 )
942
+ _ = cache .CreateWatch (& Request {ResourceNames : nil , TypeUrl : resource .ClusterType , VersionInfo : cache .getVersion ()}, wildcardState , w2 )
943
+ mustBlock (t , w2 )
944
+
945
+ // Update d, new resource in the cache
946
+ d := & cluster.Cluster {Name : "d" }
947
+ err = cache .UpdateResource ("d" , d )
948
+ require .NoError (t , err )
949
+
950
+ verifyResponseResources (t , w1 , resource .ClusterType , cache .getVersion (), "a" , "b" , "d" )
951
+ verifyResponseResources (t , w2 , resource .ClusterType , cache .getVersion (), "a" , "b" , "c" , "d" )
952
+ verifyResponseResources (t , w3 , resource .ClusterType , cache .getVersion (), "a" , "c" , "d" )
953
+ })
863
954
}
0 commit comments