Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
724 lines
26 KiB
724 lines
26 KiB
// Copyright 2022 The Gitea Authors. All rights reserved. |
|
// Use of this source code is governed by a MIT-style |
|
// license that can be found in the LICENSE file. |
|
|
|
package integrations |
|
|
|
import ( |
|
"fmt" |
|
"net/http" |
|
stdurl "net/url" |
|
"strings" |
|
"testing" |
|
"time" |
|
|
|
"code.gitea.io/gitea/models/db" |
|
"code.gitea.io/gitea/models/packages" |
|
conan_model "code.gitea.io/gitea/models/packages/conan" |
|
"code.gitea.io/gitea/models/unittest" |
|
user_model "code.gitea.io/gitea/models/user" |
|
conan_module "code.gitea.io/gitea/modules/packages/conan" |
|
"code.gitea.io/gitea/modules/setting" |
|
conan_router "code.gitea.io/gitea/routers/api/packages/conan" |
|
|
|
"github.com/stretchr/testify/assert" |
|
) |
|
|
|
const ( |
|
conanfileName = "conanfile.py" |
|
conaninfoName = "conaninfo.txt" |
|
|
|
conanLicense = "MIT" |
|
conanAuthor = "Gitea <info@gitea.io>" |
|
conanHomepage = "https://gitea.io/" |
|
conanURL = "https://gitea.com/" |
|
conanDescription = "Description of ConanPackage" |
|
conanTopic = "gitea" |
|
|
|
conanPackageReference = "dummyreference" |
|
|
|
contentConaninfo = `[settings] |
|
arch=x84_64 |
|
|
|
[requires] |
|
fmt/7.1.3 |
|
|
|
[options] |
|
shared=False |
|
|
|
[full_settings] |
|
arch=x84_64 |
|
|
|
[full_requires] |
|
fmt/7.1.3 |
|
|
|
[full_options] |
|
shared=False |
|
|
|
[recipe_hash] |
|
74714915a51073acb548ca1ce29afbac |
|
|
|
[env] |
|
CC=gcc-10` |
|
) |
|
|
|
func addTokenAuthHeader(request *http.Request, token string) *http.Request { |
|
request.Header.Set("Authorization", token) |
|
return request |
|
} |
|
|
|
func buildConanfileContent(name, version string) string { |
|
return `from conans import ConanFile, CMake, tools |
|
|
|
class ConanPackageConan(ConanFile): |
|
name = "` + name + `" |
|
version = "` + version + `" |
|
license = "` + conanLicense + `" |
|
author = "` + conanAuthor + `" |
|
homepage = "` + conanHomepage + `" |
|
url = "` + conanURL + `" |
|
description = "` + conanDescription + `" |
|
topics = ("` + conanTopic + `") |
|
settings = "os", "compiler", "build_type", "arch" |
|
options = {"shared": [True, False], "fPIC": [True, False]} |
|
default_options = {"shared": False, "fPIC": True} |
|
generators = "cmake"` |
|
} |
|
|
|
func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, channel string) { |
|
contentConanfile := buildConanfileContent(name, version) |
|
|
|
recipeURL := fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", baseURL, name, version, user, channel) |
|
|
|
req := NewRequest(t, "GET", recipeURL) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", recipeURL)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", recipeURL)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequest(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL)) |
|
MakeRequest(t, req, http.StatusUnauthorized) |
|
|
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL), map[string]int64{ |
|
conanfileName: int64(len(contentConanfile)), |
|
"removed.txt": 0, |
|
}) |
|
req = addTokenAuthHeader(req, token) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
uploadURLs := make(map[string]string) |
|
DecodeJSON(t, resp, &uploadURLs) |
|
|
|
assert.Contains(t, uploadURLs, conanfileName) |
|
assert.NotContains(t, uploadURLs, "removed.txt") |
|
|
|
uploadURL := uploadURLs[conanfileName] |
|
assert.NotEmpty(t, uploadURL) |
|
|
|
req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConanfile)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusCreated) |
|
|
|
packageURL := fmt.Sprintf("%s/packages/%s", recipeURL, conanPackageReference) |
|
|
|
req = NewRequest(t, "GET", packageURL) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", packageURL)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", packageURL)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequest(t, "POST", fmt.Sprintf("%s/upload_urls", packageURL)) |
|
MakeRequest(t, req, http.StatusUnauthorized) |
|
|
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", packageURL), map[string]int64{ |
|
conaninfoName: int64(len(contentConaninfo)), |
|
"removed.txt": 0, |
|
}) |
|
req = addTokenAuthHeader(req, token) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
uploadURLs = make(map[string]string) |
|
DecodeJSON(t, resp, &uploadURLs) |
|
|
|
assert.Contains(t, uploadURLs, conaninfoName) |
|
assert.NotContains(t, uploadURLs, "removed.txt") |
|
|
|
uploadURL = uploadURLs[conaninfoName] |
|
assert.NotEmpty(t, uploadURL) |
|
|
|
req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConaninfo)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusCreated) |
|
} |
|
|
|
func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, channel, recipeRevision, packageRevision string) { |
|
contentConanfile := buildConanfileContent(name, version) |
|
|
|
recipeURL := fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", baseURL, name, version, user, channel, recipeRevision) |
|
|
|
req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", recipeURL, conanfileName), strings.NewReader(contentConanfile)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusCreated) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/files", recipeURL)) |
|
req = addTokenAuthHeader(req, token) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
var list *struct { |
|
Files map[string]interface{} `json:"files"` |
|
} |
|
DecodeJSON(t, resp, &list) |
|
assert.Len(t, list.Files, 1) |
|
assert.Contains(t, list.Files, conanfileName) |
|
|
|
packageURL := fmt.Sprintf("%s/packages/%s/revisions/%s", recipeURL, conanPackageReference, packageRevision) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusNotFound) |
|
|
|
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", packageURL, conaninfoName), strings.NewReader(contentConaninfo)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusCreated) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)) |
|
req = addTokenAuthHeader(req, token) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
list = nil |
|
DecodeJSON(t, resp, &list) |
|
assert.Len(t, list.Files, 1) |
|
assert.Contains(t, list.Files, conaninfoName) |
|
} |
|
|
|
func TestPackageConan(t *testing.T) { |
|
defer prepareTestEnv(t)() |
|
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) |
|
|
|
name := "ConanPackage" |
|
version1 := "1.2" |
|
version2 := "1.3" |
|
user1 := "dummy" |
|
user2 := "gitea" |
|
channel1 := "test" |
|
channel2 := "final" |
|
revision1 := "rev1" |
|
revision2 := "rev2" |
|
|
|
url := fmt.Sprintf("%sapi/packages/%s/conan", setting.AppURL, user.Name) |
|
|
|
t.Run("v1", func(t *testing.T) { |
|
t.Run("Ping", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/ping", url)) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
assert.Equal(t, "revisions", resp.Header().Get("X-Conan-Server-Capabilities")) |
|
}) |
|
|
|
token := "" |
|
|
|
t.Run("Authenticate", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)) |
|
req = AddBasicAuthHeader(req, user.Name) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
body := resp.Body.String() |
|
assert.NotEmpty(t, body) |
|
|
|
token = fmt.Sprintf("Bearer %s", body) |
|
}) |
|
|
|
t.Run("CheckCredentials", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/check_credentials", url)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
}) |
|
|
|
t.Run("Upload", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
uploadConanPackageV1(t, url, token, name, version1, user1, channel1) |
|
|
|
t.Run("Validate", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeConan) |
|
assert.NoError(t, err) |
|
assert.Len(t, pvs, 1) |
|
|
|
pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) |
|
assert.NoError(t, err) |
|
assert.NotNil(t, pd.SemVer) |
|
assert.Equal(t, name, pd.Package.Name) |
|
assert.Equal(t, version1, pd.Version.Version) |
|
assert.IsType(t, &conan_module.Metadata{}, pd.Metadata) |
|
metadata := pd.Metadata.(*conan_module.Metadata) |
|
assert.Equal(t, conanLicense, metadata.License) |
|
assert.Equal(t, conanAuthor, metadata.Author) |
|
assert.Equal(t, conanHomepage, metadata.ProjectURL) |
|
assert.Equal(t, conanURL, metadata.RepositoryURL) |
|
assert.Equal(t, conanDescription, metadata.Description) |
|
assert.Equal(t, []string{conanTopic}, metadata.Keywords) |
|
|
|
pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) |
|
assert.NoError(t, err) |
|
assert.Len(t, pfs, 2) |
|
|
|
for _, pf := range pfs { |
|
pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) |
|
assert.NoError(t, err) |
|
|
|
if pf.Name == conanfileName { |
|
assert.True(t, pf.IsLead) |
|
|
|
assert.Equal(t, int64(len(buildConanfileContent(name, version1))), pb.Size) |
|
} else if pf.Name == conaninfoName { |
|
assert.False(t, pf.IsLead) |
|
|
|
assert.Equal(t, int64(len(contentConaninfo)), pb.Size) |
|
} else { |
|
assert.Fail(t, "unknown file: %s", pf.Name) |
|
} |
|
} |
|
}) |
|
}) |
|
|
|
t.Run("Download", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
recipeURL := fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, name, version1, user1, channel1) |
|
|
|
req := NewRequest(t, "GET", recipeURL) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
fileHashes := make(map[string]string) |
|
DecodeJSON(t, resp, &fileHashes) |
|
assert.Len(t, fileHashes, 1) |
|
assert.Contains(t, fileHashes, conanfileName) |
|
assert.Equal(t, "7abc52241c22090782c54731371847a8", fileHashes[conanfileName]) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", recipeURL)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
downloadURLs := make(map[string]string) |
|
DecodeJSON(t, resp, &downloadURLs) |
|
assert.Contains(t, downloadURLs, conanfileName) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", recipeURL)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
DecodeJSON(t, resp, &downloadURLs) |
|
assert.Contains(t, downloadURLs, conanfileName) |
|
|
|
req = NewRequest(t, "GET", downloadURLs[conanfileName]) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
assert.Equal(t, buildConanfileContent(name, version1), resp.Body.String()) |
|
|
|
packageURL := fmt.Sprintf("%s/packages/%s", recipeURL, conanPackageReference) |
|
|
|
req = NewRequest(t, "GET", packageURL) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
fileHashes = make(map[string]string) |
|
DecodeJSON(t, resp, &fileHashes) |
|
assert.Len(t, fileHashes, 1) |
|
assert.Contains(t, fileHashes, conaninfoName) |
|
assert.Equal(t, "7628bfcc5b17f1470c468621a78df394", fileHashes[conaninfoName]) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", packageURL)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
downloadURLs = make(map[string]string) |
|
DecodeJSON(t, resp, &downloadURLs) |
|
assert.Contains(t, downloadURLs, conaninfoName) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", packageURL)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
DecodeJSON(t, resp, &downloadURLs) |
|
assert.Contains(t, downloadURLs, conaninfoName) |
|
|
|
req = NewRequest(t, "GET", downloadURLs[conaninfoName]) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
assert.Equal(t, contentConaninfo, resp.Body.String()) |
|
}) |
|
|
|
t.Run("Search", func(t *testing.T) { |
|
uploadConanPackageV1(t, url, token, name, version2, user1, channel1) |
|
uploadConanPackageV1(t, url, token, name, version1, user1, channel2) |
|
uploadConanPackageV1(t, url, token, name, version1, user2, channel1) |
|
uploadConanPackageV1(t, url, token, name, version1, user2, channel2) |
|
|
|
t.Run("Recipe", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
cases := []struct { |
|
Query string |
|
Expected []string |
|
}{ |
|
{"ConanPackage", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.2", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.1", []string{}}, |
|
{"Conan*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/*2", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1*2", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.2@", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.2@du*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@dummy/final"}}, |
|
{"ConanPackage/1.2@du*/", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@dummy/final"}}, |
|
{"ConanPackage/1.2@du*/*test", []string{"ConanPackage/1.2@dummy/test"}}, |
|
{"ConanPackage/1.2@du*/*st", []string{"ConanPackage/1.2@dummy/test"}}, |
|
{"ConanPackage/1.2@gitea/*", []string{"ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"*/*@dummy", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@dummy/final"}}, |
|
{"*/*@*/final", []string{"ConanPackage/1.2@dummy/final", "ConanPackage/1.2@gitea/final"}}, |
|
} |
|
|
|
for i, c := range cases { |
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/conans/search?q=%s", url, stdurl.QueryEscape(c.Query))) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
var result *conan_router.SearchResult |
|
DecodeJSON(t, resp, &result) |
|
|
|
assert.ElementsMatch(t, c.Expected, result.Results, "case %d: unexpected result", i) |
|
} |
|
}) |
|
|
|
t.Run("Package", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s/search", url, name, version1, user1, channel2)) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
var result map[string]*conan_module.Conaninfo |
|
DecodeJSON(t, resp, &result) |
|
|
|
assert.Contains(t, result, conanPackageReference) |
|
info := result[conanPackageReference] |
|
assert.NotEmpty(t, info.Settings) |
|
}) |
|
}) |
|
|
|
t.Run("Delete", func(t *testing.T) { |
|
t.Run("Package", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
cases := []struct { |
|
Channel string |
|
References []string |
|
}{ |
|
{channel1, []string{conanPackageReference}}, |
|
{channel2, []string{}}, |
|
} |
|
|
|
for i, c := range cases { |
|
rref, _ := conan_module.NewRecipeReference(name, version1, user1, c.Channel, conan_module.DefaultRevision) |
|
references, err := conan_model.GetPackageReferences(db.DefaultContext, user.ID, rref) |
|
assert.NoError(t, err) |
|
assert.NotEmpty(t, references) |
|
|
|
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s/packages/delete", url, name, version1, user1, c.Channel), map[string][]string{ |
|
"package_ids": c.References, |
|
}) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
references, err = conan_model.GetPackageReferences(db.DefaultContext, user.ID, rref) |
|
assert.NoError(t, err) |
|
assert.Empty(t, references, "case %d: should be empty", i) |
|
} |
|
}) |
|
|
|
t.Run("Recipe", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
cases := []struct { |
|
Channel string |
|
}{ |
|
{channel1}, |
|
{channel2}, |
|
} |
|
|
|
for i, c := range cases { |
|
rref, _ := conan_module.NewRecipeReference(name, version1, user1, c.Channel, conan_module.DefaultRevision) |
|
revisions, err := conan_model.GetRecipeRevisions(db.DefaultContext, user.ID, rref) |
|
assert.NoError(t, err) |
|
assert.NotEmpty(t, revisions) |
|
|
|
req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, name, version1, user1, c.Channel)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
revisions, err = conan_model.GetRecipeRevisions(db.DefaultContext, user.ID, rref) |
|
assert.NoError(t, err) |
|
assert.Empty(t, revisions, "case %d: should be empty", i) |
|
} |
|
}) |
|
}) |
|
}) |
|
|
|
t.Run("v2", func(t *testing.T) { |
|
t.Run("Ping", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/ping", url)) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
assert.Equal(t, "revisions", resp.Header().Get("X-Conan-Server-Capabilities")) |
|
}) |
|
|
|
token := "" |
|
|
|
t.Run("Authenticate", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)) |
|
req = AddBasicAuthHeader(req, user.Name) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
body := resp.Body.String() |
|
assert.NotEmpty(t, body) |
|
|
|
token = fmt.Sprintf("Bearer %s", body) |
|
}) |
|
|
|
t.Run("CheckCredentials", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/check_credentials", url)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
}) |
|
|
|
t.Run("Upload", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
uploadConanPackageV2(t, url, token, name, version1, user1, channel1, revision1, revision1) |
|
|
|
t.Run("Validate", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeConan) |
|
assert.NoError(t, err) |
|
assert.Len(t, pvs, 2) |
|
}) |
|
}) |
|
|
|
t.Run("Latest", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
recipeURL := fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1) |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/latest", recipeURL)) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
obj := make(map[string]string) |
|
DecodeJSON(t, resp, &obj) |
|
assert.Contains(t, obj, "revision") |
|
assert.Equal(t, revision1, obj["revision"]) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/revisions/%s/packages/%s/latest", recipeURL, revision1, conanPackageReference)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
obj = make(map[string]string) |
|
DecodeJSON(t, resp, &obj) |
|
assert.Contains(t, obj, "revision") |
|
assert.Equal(t, revision1, obj["revision"]) |
|
}) |
|
|
|
t.Run("ListRevisions", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
uploadConanPackageV2(t, url, token, name, version1, user1, channel1, revision1, revision2) |
|
uploadConanPackageV2(t, url, token, name, version1, user1, channel1, revision2, revision1) |
|
uploadConanPackageV2(t, url, token, name, version1, user1, channel1, revision2, revision2) |
|
|
|
recipeURL := fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions", url, name, version1, user1, channel1) |
|
|
|
req := NewRequest(t, "GET", recipeURL) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
type RevisionInfo struct { |
|
Revision string `json:"revision"` |
|
Time time.Time `json:"time"` |
|
} |
|
|
|
type RevisionList struct { |
|
Revisions []*RevisionInfo `json:"revisions"` |
|
} |
|
|
|
var list *RevisionList |
|
DecodeJSON(t, resp, &list) |
|
assert.Len(t, list.Revisions, 2) |
|
revs := make([]string, 0, len(list.Revisions)) |
|
for _, rev := range list.Revisions { |
|
revs = append(revs, rev.Revision) |
|
} |
|
assert.ElementsMatch(t, []string{revision1, revision2}, revs) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/packages/%s/revisions", recipeURL, revision1, conanPackageReference)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
DecodeJSON(t, resp, &list) |
|
assert.Len(t, list.Revisions, 2) |
|
revs = make([]string, 0, len(list.Revisions)) |
|
for _, rev := range list.Revisions { |
|
revs = append(revs, rev.Revision) |
|
} |
|
assert.ElementsMatch(t, []string{revision1, revision2}, revs) |
|
}) |
|
|
|
t.Run("Search", func(t *testing.T) { |
|
t.Run("Recipe", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
cases := []struct { |
|
Query string |
|
Expected []string |
|
}{ |
|
{"ConanPackage", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.2", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.1", []string{}}, |
|
{"Conan*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1*", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/*2", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1*2", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.2@", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"ConanPackage/1.2@du*", []string{"ConanPackage/1.2@dummy/test"}}, |
|
{"ConanPackage/1.2@du*/", []string{"ConanPackage/1.2@dummy/test"}}, |
|
{"ConanPackage/1.2@du*/*test", []string{"ConanPackage/1.2@dummy/test"}}, |
|
{"ConanPackage/1.2@du*/*st", []string{"ConanPackage/1.2@dummy/test"}}, |
|
{"ConanPackage/1.2@gitea/*", []string{"ConanPackage/1.2@gitea/test", "ConanPackage/1.2@gitea/final"}}, |
|
{"*/*@dummy", []string{"ConanPackage/1.2@dummy/test", "ConanPackage/1.3@dummy/test"}}, |
|
{"*/*@*/final", []string{"ConanPackage/1.2@gitea/final"}}, |
|
} |
|
|
|
for i, c := range cases { |
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/conans/search?q=%s", url, stdurl.QueryEscape(c.Query))) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
var result *conan_router.SearchResult |
|
DecodeJSON(t, resp, &result) |
|
|
|
assert.ElementsMatch(t, c.Expected, result.Results, "case %d: unexpected result", i) |
|
} |
|
}) |
|
|
|
t.Run("Package", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/search", url, name, version1, user1, channel1)) |
|
resp := MakeRequest(t, req, http.StatusOK) |
|
|
|
var result map[string]*conan_module.Conaninfo |
|
DecodeJSON(t, resp, &result) |
|
|
|
assert.Contains(t, result, conanPackageReference) |
|
info := result[conanPackageReference] |
|
assert.NotEmpty(t, info.Settings) |
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/search", url, name, version1, user1, channel1, revision1)) |
|
resp = MakeRequest(t, req, http.StatusOK) |
|
|
|
result = make(map[string]*conan_module.Conaninfo) |
|
DecodeJSON(t, resp, &result) |
|
|
|
assert.Contains(t, result, conanPackageReference) |
|
info = result[conanPackageReference] |
|
assert.NotEmpty(t, info.Settings) |
|
}) |
|
}) |
|
|
|
t.Run("Delete", func(t *testing.T) { |
|
t.Run("Package", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
rref, _ := conan_module.NewRecipeReference(name, version1, user1, channel1, revision1) |
|
pref, _ := conan_module.NewPackageReference(rref, conanPackageReference, conan_module.DefaultRevision) |
|
|
|
checkPackageRevisionCount := func(count int) { |
|
revisions, err := conan_model.GetPackageRevisions(db.DefaultContext, user.ID, pref) |
|
assert.NoError(t, err) |
|
assert.Len(t, revisions, count) |
|
} |
|
checkPackageReferenceCount := func(count int) { |
|
references, err := conan_model.GetPackageReferences(db.DefaultContext, user.ID, rref) |
|
assert.NoError(t, err) |
|
assert.Len(t, references, count) |
|
} |
|
|
|
checkPackageRevisionCount(2) |
|
|
|
req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s/revisions/%s", url, name, version1, user1, channel1, revision1, conanPackageReference, revision1)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
checkPackageRevisionCount(1) |
|
|
|
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s", url, name, version1, user1, channel1, revision1, conanPackageReference)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
checkPackageRevisionCount(0) |
|
|
|
rref = rref.WithRevision(revision2) |
|
|
|
checkPackageReferenceCount(1) |
|
|
|
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages", url, name, version1, user1, channel1, revision2)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
checkPackageReferenceCount(0) |
|
}) |
|
|
|
t.Run("Recipe", func(t *testing.T) { |
|
defer PrintCurrentTest(t)() |
|
|
|
rref, _ := conan_module.NewRecipeReference(name, version1, user1, channel1, conan_module.DefaultRevision) |
|
|
|
checkRecipeRevisionCount := func(count int) { |
|
revisions, err := conan_model.GetRecipeRevisions(db.DefaultContext, user.ID, rref) |
|
assert.NoError(t, err) |
|
assert.Len(t, revisions, count) |
|
} |
|
|
|
checkRecipeRevisionCount(2) |
|
|
|
req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", url, name, version1, user1, channel1, revision1)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
checkRecipeRevisionCount(1) |
|
|
|
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1)) |
|
req = addTokenAuthHeader(req, token) |
|
MakeRequest(t, req, http.StatusOK) |
|
|
|
checkRecipeRevisionCount(0) |
|
}) |
|
}) |
|
}) |
|
}
|
|
|