Revert "ci: skip "lib/test-fork-safe-execvpe.sh" on Alpine Linux"
[libnbd.git] / golang / libnbd_240_opt_list_meta_test.go
blob0235fe3f8f453de17053b60a05f7fba2ce90b844
1 /* libnbd golang tests
2 * Copyright Red Hat
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 package libnbd
21 import (
22 "fmt";
23 "testing"
26 var list_count uint
27 var list_seen bool
29 func listmetaf(user_data int, name string) int {
30 if user_data != 42 {
31 panic("expected user_data == 42")
33 list_count++
34 if (name == context_base_allocation) {
35 list_seen = true
37 return 0
40 func Test240OptListMeta(t *testing.T) {
41 /* Get into negotiating state. */
42 h, err := Create()
43 if err != nil {
44 t.Fatalf("could not create handle: %s", err)
46 defer h.Close()
48 err = h.SetOptMode(true)
49 if err != nil {
50 t.Fatalf("could not set opt mode: %s", err)
53 err = h.ConnectCommand([]string{
54 "nbdkit", "-s", "--exit-with-parent", "-v",
55 "memory", "size=1M",
57 if err != nil {
58 t.Fatalf("could not connect: %s", err)
61 /* First pass: empty query should give at least "base:allocation". */
62 list_count = 0
63 list_seen = false
64 r, err := h.OptListMetaContext(func(name string) int {
65 return listmetaf(42, name)
67 if err != nil {
68 t.Fatalf("could not request opt_list_meta_context: %s", err)
70 if r != list_count || r < 1 || !list_seen {
71 t.Fatalf("unexpected count after opt_list_meta_context")
73 max := list_count
75 /* Second pass: bogus query has no response. */
76 list_count = 0
77 list_seen = false
78 err = h.AddMetaContext("x-nosuch:")
79 if err != nil {
80 t.Fatalf("could not request add_meta_context: %s", err)
82 r, err = h.OptListMetaContext(func(name string) int {
83 return listmetaf(42, name)
85 if err != nil {
86 t.Fatalf("could not request opt_list_meta_context: %s", err)
88 if r != 0 || r != list_count || list_seen {
89 t.Fatalf("unexpected count after opt_list_meta_context")
92 /* Third pass: specific query should have one match. */
93 list_count = 0
94 list_seen = false
95 err = h.AddMetaContext(context_base_allocation)
96 if err != nil {
97 t.Fatalf("could not request add_meta_context: %s", err)
99 r, err = h.GetNrMetaContexts()
100 if err != nil {
101 t.Fatalf("could not request get_nr_meta_contexts: %s", err)
103 if r != 2 {
104 t.Fatalf("wrong number of meta_contexts: %d", r)
106 tmp, err := h.GetMetaContext(1)
107 if err != nil {
108 t.Fatalf("could not request get_meta_context: %s", err)
110 if *tmp != context_base_allocation {
111 t.Fatalf("wrong result of get_meta_context: %s", *tmp)
113 r, err = h.OptListMetaContext(func(name string) int {
114 return listmetaf(42, name)
116 if err != nil {
117 t.Fatalf("could not request opt_list_meta_context: %s", err)
119 if r != 1 || r != list_count || !list_seen {
120 t.Fatalf("unexpected count after opt_list_meta_context")
123 /* Fourth pass: opt_list_meta_context is stateless, so it should
124 * not wipe status learned during opt_info
126 list_count = 0
127 list_seen = false
128 _, err = h.GetSize()
129 if err == nil {
130 t.Fatalf("expected error")
132 _, err = h.CanMetaContext(context_base_allocation)
133 if err == nil {
134 t.Fatalf("expected error")
136 err = h.OptInfo()
137 if err != nil {
138 t.Fatalf("opt_info failed unexpectedly: %s", err)
140 size, err := h.GetSize()
141 if err != nil {
142 t.Fatalf("get_size failed unexpectedly: %s", err)
144 if size != 1048576 {
145 t.Fatalf("get_size gave wrong size")
147 meta, err := h.CanMetaContext(context_base_allocation)
148 if err != nil {
149 t.Fatalf("can_meta_context failed unexpectedly: %s", err)
151 if !meta {
152 t.Fatalf("unexpected count after can_meta_context")
154 err = h.ClearMetaContexts()
155 if err != nil {
156 t.Fatalf("could not request clear_meta_contexts: %s", err)
158 err = h.AddMetaContext("x-nosuch:")
159 if err != nil {
160 t.Fatalf("could not request add_meta_context: %s", err)
162 r, err = h.OptListMetaContext(func(name string) int {
163 return listmetaf(42, name)
165 if err != nil {
166 t.Fatalf("could not request opt_list_meta_context: %s", err)
168 if r != 0 || r != list_count || list_seen {
169 t.Fatalf("unexpected count after opt_list_meta_context")
171 size, err = h.GetSize()
172 if err != nil {
173 t.Fatalf("get_size failed unexpectedly: %s", err)
175 if size != 1048576 {
176 t.Fatalf("get_size gave wrong size")
178 meta, err = h.CanMetaContext(context_base_allocation)
179 if err != nil {
180 t.Fatalf("can_meta_context failed unexpectedly: %s", err)
182 if !meta {
183 t.Fatalf("unexpected count after can_meta_context")
185 err = h.ClearMetaContexts()
187 /* Final pass: "base:" query should get at least "base:allocation" */
188 list_count = 0
189 list_seen = false
190 err = h.AddMetaContext("base:")
191 if err != nil {
192 t.Fatalf("could not request add_meta_context: %s", err)
194 r, err = h.OptListMetaContext(func(name string) int {
195 return listmetaf(42, name)
197 if err != nil {
198 t.Fatalf("could not request opt_list_meta_context: %s", err)
200 if r < 1 || r > max || r != list_count || !list_seen {
201 t.Fatalf("unexpected count after opt_list_meta_context")
204 err = h.OptAbort()
205 if err != nil {
206 t.Fatalf("could not request opt_abort: %s", err)
209 /* Repeat but this time without structured replies. Deal gracefully
210 * with older servers that don't allow the attempt.
212 h, err = Create()
213 if err != nil {
214 t.Fatalf("could not create handle: %s", err)
216 defer h.Close()
218 err = h.SetOptMode(true)
219 if err != nil {
220 t.Fatalf("could not set opt mode: %s", err)
223 err = h.SetRequestStructuredReplies(false)
224 if err != nil {
225 t.Fatalf("could not set request structured replies: %s", err)
228 err = h.ConnectCommand([]string{
229 "nbdkit", "-s", "--exit-with-parent", "-v",
230 "memory", "size=1M",
232 if err != nil {
233 t.Fatalf("could not connect: %s", err)
236 bytes, err := h.StatsBytesSent()
237 if err != nil {
238 t.Fatalf("could not collect stats: %s", err)
241 list_count = 0
242 list_seen = false
243 r, err = h.OptListMetaContext(func(name string) int {
244 return listmetaf(42, name)
246 if err != nil {
247 bytes2, err2 := h.StatsBytesSent()
248 if err2 != nil {
249 t.Fatalf("could not collect stats: %s", err2)
251 if bytes2 <= bytes {
252 t.Fatalf("unexpected bytes sent after opt_list_meta_context")
254 fmt.Printf("ignoring failure from old server: %s", err)
255 } else if r < 1 || r != list_count || !list_seen {
256 t.Fatalf("unexpected count after opt_list_meta_context")
259 /* Now enable structured replies, and a retry should pass. */
260 sr, err := h.OptStructuredReply()
261 if err != nil {
262 t.Fatalf("could not request opt_structured_reply: %s", err)
264 if !sr {
265 t.Fatalf("structured replies not enabled: %s", err)
268 list_count = 0
269 list_seen = false
270 r, err = h.OptListMetaContext(func(name string) int {
271 return listmetaf(42, name)
273 if err != nil {
274 t.Fatalf("could not request opt_list_meta_context: %s", err)
276 if r < 1 || r != list_count || !list_seen {
277 t.Fatalf("unexpected count after opt_list_meta_context")
280 err = h.OptAbort()
281 if err != nil {
282 t.Fatalf("could not request opt_abort: %s", err)