Files
forge/tests/integration/api_packages_conda_test.go
zeekayandHanzo Dev 9a07b4d089 legal: Hanzo AI, Inc. copyright above the upstream notices
2978 files. The fork is 2026-07-15 (rebrand: gitea.dev -> github.com/hanzoai/git),
so 2026 is the year, and "Copyright 2026 Hanzo AI, Inc." was already the form
used by the handful of files that had ours.

Shape is now:

	// Copyright 2026 Hanzo AI, Inc. All rights reserved.
	// Copyright 2015 The Gogs Authors. All rights reserved.
	// Copyright 2019 The Gitea Authors. All rights reserved.
	// SPDX-License-Identifier: MIT

Ours on top, theirs retained verbatim. Retained because MIT requires it, and
separately because they are true — those authors did write that code.

Not renamed to "The Git Authors": Git is a different project under a different
license, and putting its name here would attribute this code to people who have
nothing to do with it. Adding our line is the fix; overwriting theirs would have
been both a licence violation and a false statement.

gofmt still reports import-order drift in some of these files. It predates this
change (verified against a stash) and is left alone rather than burying a
one-line-per-file legal change under 3000 files of unrelated reordering.

Build clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:49:52 -07:00

275 lines
9.2 KiB
Go

// Copyright 2026 Hanzo AI, Inc. All rights reserved.
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"archive/tar"
"bytes"
"fmt"
"io"
"net/http"
"testing"
"github.com/hanzoai/git/models/packages"
"github.com/hanzoai/git/models/unittest"
user_model "github.com/hanzoai/git/models/user"
conda_module "github.com/hanzoai/git/modules/packages/conda"
"github.com/hanzoai/git/modules/test"
"github.com/hanzoai/git/modules/zstd"
"github.com/hanzoai/git/tests"
"github.com/dsnet/compress/bzip2"
"github.com/stretchr/testify/assert"
)
func TestPackageConda(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "test_package"
packageVersion := "1.0.1"
channel := "test-channel"
root := fmt.Sprintf("/v1/packages/%s/conda", user.Name)
t.Run("Upload", func(t *testing.T) {
tarContent := func() []byte {
var buf bytes.Buffer
tw := tar.NewWriter(&buf)
content := []byte(`{"name":"` + packageName + `","version":"` + packageVersion + `","subdir":"noarch","build":"xxx"}`)
hdr := &tar.Header{
Name: "info/index.json",
Mode: 0o600,
Size: int64(len(content)),
}
tw.WriteHeader(hdr)
tw.Write(content)
tw.Close()
return buf.Bytes()
}()
t.Run(".tar.bz2", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
var buf bytes.Buffer
bw, _ := bzip2.NewWriter(&buf, nil)
io.Copy(bw, bytes.NewReader(tarContent))
bw.Close()
filename := fmt.Sprintf("%s-%s.tar.bz2", packageName, packageVersion)
req := NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes()))
MakeRequest(t, req, http.StatusUnauthorized)
req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())).
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusCreated)
req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())).
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusConflict)
pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeConda)
assert.NoError(t, err)
assert.Len(t, pvs, 1)
pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
assert.NoError(t, err)
assert.Nil(t, pd.SemVer)
assert.IsType(t, &conda_module.VersionMetadata{}, pd.Metadata)
assert.Equal(t, packageName, pd.Package.Name)
assert.Equal(t, packageVersion, pd.Version.Version)
assert.Empty(t, pd.PackageProperties.GetByName(conda_module.PropertyChannel))
})
t.Run(".conda", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
var infoBuf bytes.Buffer
zsw, _ := zstd.NewWriter(&infoBuf)
io.Copy(zsw, bytes.NewReader(tarContent))
zsw.Close()
buf := test.WriteZipArchive(map[string]string{
"info-x.tar.zst": infoBuf.String(),
})
fullName := channel + "/" + packageName
filename := fmt.Sprintf("%s-%s.conda", packageName, packageVersion)
req := NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes()))
MakeRequest(t, req, http.StatusUnauthorized)
req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())).
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusCreated)
req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())).
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusConflict)
pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeConda)
assert.NoError(t, err)
assert.Len(t, pvs, 2)
pds, err := packages.GetPackageDescriptors(t.Context(), pvs)
assert.NoError(t, err)
assert.Condition(t, func() bool {
for _, pd := range pds {
if pd.Package.Name == fullName {
return true
}
}
return false
})
for _, pd := range pds {
if pd.Package.Name == fullName {
assert.Nil(t, pd.SemVer)
assert.IsType(t, &conda_module.VersionMetadata{}, pd.Metadata)
assert.Equal(t, fullName, pd.Package.Name)
assert.Equal(t, packageVersion, pd.Version.Version)
assert.Equal(t, channel, pd.PackageProperties.GetByName(conda_module.PropertyChannel))
}
}
})
})
t.Run("Download", func(t *testing.T) {
t.Run(".tar.bz2", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", fmt.Sprintf("%s/noarch/%s-%s-xxx.tar.bz2", root, packageName, packageVersion))
MakeRequest(t, req, http.StatusOK)
req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/noarch/%s-%s-xxx.tar.bz2", root, channel, packageName, packageVersion))
MakeRequest(t, req, http.StatusNotFound)
})
t.Run(".conda", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", fmt.Sprintf("%s/noarch/%s-%s-xxx.conda", root, packageName, packageVersion))
MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/noarch/%s-%s-xxx.conda", root, channel, packageName, packageVersion))
MakeRequest(t, req, http.StatusOK)
})
})
t.Run("EnumeratePackages", func(t *testing.T) {
type Info struct {
Subdir string `json:"subdir"`
}
type PackageInfo struct {
Name string `json:"name"`
Version string `json:"version"`
NoArch string `json:"noarch"`
Subdir string `json:"subdir"`
Timestamp int64 `json:"timestamp"`
Build string `json:"build"`
BuildNumber int64 `json:"build_number"`
Dependencies []string `json:"depends"`
License string `json:"license"`
LicenseFamily string `json:"license_family"`
HashMD5 string `json:"md5"`
HashSHA256 string `json:"sha256"`
Size int64 `json:"size"`
}
type RepoData struct {
Info Info `json:"info"`
Packages map[string]*PackageInfo `json:"packages"`
PackagesConda map[string]*PackageInfo `json:"packages.conda"`
Removed map[string]*PackageInfo `json:"removed"`
}
req := NewRequest(t, "GET", root+"/noarch/repodata.json")
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
req = NewRequest(t, "GET", root+"/noarch/repodata.json.bz2")
resp = MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "application/x-bzip2", resp.Header().Get("Content-Type"))
req = NewRequest(t, "GET", root+"/noarch/current_repodata.json")
resp = MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
req = NewRequest(t, "GET", root+"/noarch/current_repodata.json.bz2")
resp = MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "application/x-bzip2", resp.Header().Get("Content-Type"))
t.Run(".tar.bz2", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
pv, err := packages.GetVersionByNameAndVersion(t.Context(), user.ID, packages.TypeConda, packageName, packageVersion)
assert.NoError(t, err)
pd, err := packages.GetPackageDescriptor(t.Context(), pv)
assert.NoError(t, err)
req := NewRequest(t, "GET", root+"/noarch/repodata.json")
resp := MakeRequest(t, req, http.StatusOK)
result := DecodeJSON(t, resp, &RepoData{})
assert.Equal(t, "noarch", result.Info.Subdir)
assert.Empty(t, result.PackagesConda)
assert.Empty(t, result.Removed)
filename := fmt.Sprintf("%s-%s-xxx.tar.bz2", packageName, packageVersion)
assert.Contains(t, result.Packages, filename)
packageInfo := result.Packages[filename]
assert.Equal(t, packageName, packageInfo.Name)
assert.Equal(t, packageVersion, packageInfo.Version)
assert.Equal(t, "noarch", packageInfo.Subdir)
assert.Equal(t, "xxx", packageInfo.Build)
assert.Equal(t, pd.Files[0].Blob.HashMD5, packageInfo.HashMD5)
assert.Equal(t, pd.Files[0].Blob.HashSHA256, packageInfo.HashSHA256)
assert.Equal(t, pd.Files[0].Blob.Size, packageInfo.Size)
assert.NotNil(t, packageInfo.Dependencies)
assert.Empty(t, packageInfo.Dependencies)
})
t.Run(".conda", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
pv, err := packages.GetVersionByNameAndVersion(t.Context(), user.ID, packages.TypeConda, channel+"/"+packageName, packageVersion)
assert.NoError(t, err)
pd, err := packages.GetPackageDescriptor(t.Context(), pv)
assert.NoError(t, err)
req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/noarch/repodata.json", root, channel))
resp := MakeRequest(t, req, http.StatusOK)
result := DecodeJSON(t, resp, &RepoData{})
assert.Equal(t, "noarch", result.Info.Subdir)
assert.Empty(t, result.Packages)
assert.Empty(t, result.Removed)
filename := fmt.Sprintf("%s-%s-xxx.conda", packageName, packageVersion)
assert.Contains(t, result.PackagesConda, filename)
packageInfo := result.PackagesConda[filename]
assert.Equal(t, packageName, packageInfo.Name)
assert.Equal(t, packageVersion, packageInfo.Version)
assert.Equal(t, "noarch", packageInfo.Subdir)
assert.Equal(t, "xxx", packageInfo.Build)
assert.Equal(t, pd.Files[0].Blob.HashMD5, packageInfo.HashMD5)
assert.Equal(t, pd.Files[0].Blob.HashSHA256, packageInfo.HashSHA256)
assert.Equal(t, pd.Files[0].Blob.Size, packageInfo.Size)
assert.NotNil(t, packageInfo.Dependencies)
assert.Empty(t, packageInfo.Dependencies)
})
})
}