test: expand server test (pypi/rpm local, object evict, validation errors)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -235,6 +236,99 @@ func TestServerProbe(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func put(t *testing.T, path string, body []byte) (*http.Response, []byte) {
|
||||||
|
t.Helper()
|
||||||
|
rq, _ := http.NewRequest("PUT", testTS.URL+path, bytes.NewReader(body))
|
||||||
|
resp, err := http.DefaultClient.Do(rq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("PUT %s: %v", path, err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
b, _ := io.ReadAll(resp.Body)
|
||||||
|
return resp, b
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerLocalPyPI(t *testing.T) {
|
||||||
|
requireStack(t)
|
||||||
|
if resp, b := req(t, "POST", "/api/v2/remotes", `{"name":"srv-pypi","package_type":"pypi","repo_type":"local"}`); resp.StatusCode != 201 {
|
||||||
|
t.Fatalf("create pypi local: %d %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
defer req(t, "DELETE", "/api/v2/remotes/srv-pypi", "")
|
||||||
|
|
||||||
|
if resp, b := put(t, "/api/v2/remotes/srv-pypi/files/foo-1.0-py3-none-any.whl", []byte("wheel bytes")); resp.StatusCode != 201 {
|
||||||
|
t.Fatalf("upload wheel: %d %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
// Re-uploading the same file is rejected.
|
||||||
|
if resp, _ := put(t, "/api/v2/remotes/srv-pypi/files/foo-1.0-py3-none-any.whl", []byte("again")); resp.StatusCode != 409 {
|
||||||
|
t.Errorf("expected 409 on overwrite, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
// Invalid pypi filename rejected.
|
||||||
|
if resp, _ := put(t, "/api/v2/remotes/srv-pypi/files/not-a-package.txt", []byte("x")); resp.StatusCode != 400 {
|
||||||
|
t.Errorf("expected 400 for bad filename, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp, b := req(t, "GET", "/api/v1/local/srv-pypi/simple/", ""); resp.StatusCode != 200 || !strings.Contains(string(b), "foo") {
|
||||||
|
t.Errorf("simple index: %d %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
if resp, b := req(t, "GET", "/api/v1/local/srv-pypi/simple/foo/", ""); resp.StatusCode != 200 || !strings.Contains(string(b), "foo-1.0-py3-none-any.whl") {
|
||||||
|
t.Errorf("package index: %d %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerLocalRPMRepodata(t *testing.T) {
|
||||||
|
requireStack(t)
|
||||||
|
rpm, err := os.ReadFile("../provider/rpm/testdata/e2e-testpkg-1.0-1.noarch.rpm")
|
||||||
|
if err != nil {
|
||||||
|
t.Skipf("rpm fixture unavailable: %v", err)
|
||||||
|
}
|
||||||
|
if resp, b := req(t, "POST", "/api/v2/remotes", `{"name":"srv-rpm","package_type":"rpm","repo_type":"local"}`); resp.StatusCode != 201 {
|
||||||
|
t.Fatalf("create rpm local: %d %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
defer req(t, "DELETE", "/api/v2/remotes/srv-rpm", "")
|
||||||
|
|
||||||
|
if resp, b := put(t, "/api/v2/remotes/srv-rpm/files/e2e-testpkg-1.0-1.noarch.rpm", rpm); resp.StatusCode != 201 {
|
||||||
|
t.Fatalf("upload rpm: %d %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// repodata is generated asynchronously; poll for it.
|
||||||
|
var body []byte
|
||||||
|
for i := 0; i < 40; i++ {
|
||||||
|
var resp *http.Response
|
||||||
|
resp, body = req(t, "GET", "/api/v1/local/srv-rpm/repodata/repomd.xml", "")
|
||||||
|
if resp.StatusCode == 200 && strings.Contains(string(body), "<repomd") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
}
|
||||||
|
t.Errorf("repomd.xml not generated: %s", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerObjectEviction(t *testing.T) {
|
||||||
|
requireStack(t)
|
||||||
|
create := fmt.Sprintf(`{"name":"srv-evict","package_type":"generic","repo_type":"remote","base_url":%q,"stale_on_error":true}`, upstream.URL)
|
||||||
|
req(t, "POST", "/api/v2/remotes", create)
|
||||||
|
defer req(t, "DELETE", "/api/v2/remotes/srv-evict", "")
|
||||||
|
|
||||||
|
resp, _ := req(t, "GET", "/api/v1/remote/srv-evict/data/file.bin", "")
|
||||||
|
resp.Body.Close()
|
||||||
|
if resp, _ := req(t, "DELETE", "/api/v2/remotes/srv-evict/objects/data/file.bin", ""); resp.StatusCode >= 400 {
|
||||||
|
t.Errorf("evict object: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerValidationErrors(t *testing.T) {
|
||||||
|
requireStack(t)
|
||||||
|
if resp, _ := req(t, "POST", "/api/v2/remotes", `{"name":"bad","package_type":"bogus","base_url":"https://x"}`); resp.StatusCode != 400 {
|
||||||
|
t.Errorf("invalid package type: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
if resp, _ := req(t, "POST", "/api/v2/remotes", `{"name":"bad","package_type":"generic","repo_type":"remote"}`); resp.StatusCode != 400 {
|
||||||
|
t.Errorf("missing base_url: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
if resp, _ := req(t, "POST", "/api/v2/remotes", `not json`); resp.StatusCode != 400 {
|
||||||
|
t.Errorf("invalid json: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestServerNotFound(t *testing.T) {
|
func TestServerNotFound(t *testing.T) {
|
||||||
requireStack(t)
|
requireStack(t)
|
||||||
if resp, _ := req(t, "GET", "/api/v2/remotes/does-not-exist", ""); resp.StatusCode != 404 {
|
if resp, _ := req(t, "GET", "/api/v2/remotes/does-not-exist", ""); resp.StatusCode != 404 {
|
||||||
|
|||||||
Reference in New Issue
Block a user