| 245 | } |
| 246 | |
| 247 | func (a *APIClient) request(path string, in, out any, wantErr bool) { |
| 248 | t := a.t |
| 249 | var ( |
| 250 | dataIn []byte |
| 251 | dataOut []byte |
| 252 | err error |
| 253 | ) |
| 254 | |
| 255 | realm := "VolumeDriver" |
| 256 | if path == "Activate" { |
| 257 | realm = "Plugin" |
| 258 | } |
| 259 | url := fmt.Sprintf("http://%s/%s.%s", a.host, realm, path) |
| 260 | |
| 261 | if str, isString := in.(string); isString { |
| 262 | dataIn = []byte(str) |
| 263 | } else { |
| 264 | dataIn, err = json.Marshal(in) |
| 265 | require.NoError(t, err) |
| 266 | } |
| 267 | fs.Logf(path, "<-- %s", dataIn) |
| 268 | |
| 269 | req, err := http.NewRequest("POST", url, bytes.NewBuffer(dataIn)) |
| 270 | require.NoError(t, err) |
| 271 | req.Header.Set("Content-Type", "application/json") |
| 272 | |
| 273 | res, err := a.cli.Do(req) |
| 274 | require.NoError(t, err) |
| 275 | |
| 276 | wantStatus := http.StatusOK |
| 277 | if wantErr { |
| 278 | wantStatus = http.StatusInternalServerError |
| 279 | } |
| 280 | assert.Equal(t, wantStatus, res.StatusCode) |
| 281 | |
| 282 | dataOut, err = io.ReadAll(res.Body) |
| 283 | require.NoError(t, err) |
| 284 | err = res.Body.Close() |
| 285 | require.NoError(t, err) |
| 286 | |
| 287 | if strPtr, isString := out.(*string); isString || wantErr { |
| 288 | require.True(t, isString, "must use string for error response") |
| 289 | if wantErr { |
| 290 | var errRes docker.ErrorResponse |
| 291 | err = json.Unmarshal(dataOut, &errRes) |
| 292 | require.NoError(t, err) |
| 293 | *strPtr = errRes.Err |
| 294 | } else { |
| 295 | *strPtr = strings.TrimSpace(string(dataOut)) |
| 296 | } |
| 297 | } else { |
| 298 | err = json.Unmarshal(dataOut, out) |
| 299 | require.NoError(t, err) |
| 300 | } |
| 301 | fs.Logf(path, "--> %s", dataOut) |
| 302 | time.Sleep(tempDelay) |
| 303 | } |
| 304 | |