@@ -17,6 +17,7 @@ limitations under the License.
1717package rest
1818
1919import (
20+ "encoding/json"
2021 "net/http"
2122 "testing"
2223
@@ -71,6 +72,79 @@ func TestResourcesViewAcrossNodes(t *testing.T) {
7172 }
7273}
7374
75+ // TestResourcesViewNodeFilter: ?nodes=n1 returns only the n1 replicas.
76+ // Case-insensitive matching mirrors Java LINSTOR behaviour so a client
77+ // sending mixed-case node names still gets results.
78+ func TestResourcesViewNodeFilter (t * testing.T ) {
79+ st := store .NewInMemory ()
80+ ctx := t .Context ()
81+
82+ for _ , r := range []apiv1.Resource {
83+ {Name : "pvc-1" , NodeName : "n1" },
84+ {Name : "pvc-1" , NodeName : "n2" },
85+ {Name : "pvc-2" , NodeName : "n2" },
86+ } {
87+ if err := st .Resources ().Create (ctx , & r ); err != nil {
88+ t .Fatalf ("seed: %v" , err )
89+ }
90+ }
91+
92+ base , stop := startServerWithStore (t , st )
93+ defer stop ()
94+
95+ resp := httpGet (t , base + "/v1/view/resources?nodes=N1" )
96+ defer func () { _ = resp .Body .Close () }()
97+
98+ if resp .StatusCode != http .StatusOK {
99+ t .Fatalf ("status: got %d, want 200" , resp .StatusCode )
100+ }
101+
102+ var got []apiv1.ResourceWithVolumes
103+
104+ if err := json .NewDecoder (resp .Body ).Decode (& got ); err != nil {
105+ t .Fatalf ("decode: %v" , err )
106+ }
107+
108+ if len (got ) != 1 {
109+ t .Fatalf ("len: got %d, want 1; entries=%v" , len (got ), got )
110+ }
111+
112+ if got [0 ].NodeName != "n1" {
113+ t .Errorf ("filter leaked: got node %q, want n1" , got [0 ].NodeName )
114+ }
115+ }
116+
117+ // TestResourcesViewRDFilter: ?resources=pvc-1 returns only that RD's replicas.
118+ func TestResourcesViewRDFilter (t * testing.T ) {
119+ st := store .NewInMemory ()
120+ ctx := t .Context ()
121+
122+ for _ , r := range []apiv1.Resource {
123+ {Name : "pvc-1" , NodeName : "n1" },
124+ {Name : "pvc-2" , NodeName : "n2" },
125+ } {
126+ if err := st .Resources ().Create (ctx , & r ); err != nil {
127+ t .Fatalf ("seed: %v" , err )
128+ }
129+ }
130+
131+ base , stop := startServerWithStore (t , st )
132+ defer stop ()
133+
134+ resp := httpGet (t , base + "/v1/view/resources?resources=pvc-1" )
135+ defer func () { _ = resp .Body .Close () }()
136+
137+ var got []apiv1.ResourceWithVolumes
138+
139+ if err := json .NewDecoder (resp .Body ).Decode (& got ); err != nil {
140+ t .Fatalf ("decode: %v" , err )
141+ }
142+
143+ if len (got ) != 1 || got [0 ].Name != "pvc-1" {
144+ t .Errorf ("got %v, want one entry for pvc-1" , got )
145+ }
146+ }
147+
74148// TestResourcesViewWithoutStore: 503 when store is nil.
75149func TestResourcesViewWithoutStore (t * testing.T ) {
76150 base , stop := startServerCustom (t , & Server {Addr : pickFreeAddr (t ), Store : nil })
0 commit comments