goproxy/pkg/proxy/proxy_test.go

320 lines
6.9 KiB
Go

package proxy
import (
"archive/zip"
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"os"
"reflect"
"strings"
"testing"
"time"
"github.com/goproxyio/goproxy/pkg/modfetch"
"github.com/goproxyio/goproxy/pkg/module"
"github.com/goproxyio/goproxy/pkg/testenv"
)
var _handle http.Handler
func TestMain(m *testing.M) {
tmpdir, err := ioutil.TempDir("", "goproxy-test-")
if err != nil {
log.Fatalf("init tmpdir failed: %s", err)
}
defer os.RemoveAll(tmpdir)
_handle = NewProxy(tmpdir)
os.Exit(m.Run())
}
var _modInfoTests = []struct {
path string
version string
latest bool
time time.Time
gomod string
zip []string
versions []string
}{
{
path: "gopkg.in/check.v1",
version: "v0.0.0-20161208181325-20d25e280405",
time: time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC),
gomod: "module gopkg.in/check.v1\n",
zip: []string{
".gitignore",
".travis.yml",
"LICENSE",
"README.md",
"TODO",
"benchmark.go",
"benchmark_test.go",
"bootstrap_test.go",
"check.go",
"check_test.go",
"checkers.go",
"checkers_test.go",
"export_test.go",
"fixture_test.go",
"foundation_test.go",
"helpers.go",
"helpers_test.go",
"printer.go",
"printer_test.go",
"reporter.go",
"reporter_test.go",
"run.go",
"run_test.go",
},
},
{
path: "github.com/PuerkitoBio/goquery",
version: "v0.0.0-20181014175806-2af3d16e2bb8",
time: time.Date(2018, 10, 14, 17, 58, 6, 0, time.UTC),
gomod: "module github.com/PuerkitoBio/goquery\n",
zip: []string{
".gitattributes",
".gitignore",
".travis.yml",
"LICENSE",
"README.md",
"array.go",
"array_test.go",
"bench/v0.1.0",
"bench/v0.1.1",
"bench/v0.1.1-v0.2.1-go1.1rc1.svg",
"bench/v0.2.0",
"bench/v0.2.0-v0.2.1-go1.1rc1.svg",
"bench/v0.2.1-go1.1rc1",
"bench/v0.3.0",
"bench/v0.3.2-go1.2",
"bench/v0.3.2-go1.2-take2",
"bench/v0.3.2-go1.2rc1",
"bench/v1.0.0-go1.7",
"bench/v1.0.1a-go1.7",
"bench/v1.0.1b-go1.7",
"bench/v1.0.1c-go1.7",
"bench_array_test.go",
"bench_example_test.go",
"bench_expand_test.go",
"bench_filter_test.go",
"bench_iteration_test.go",
"bench_property_test.go",
"bench_query_test.go",
"bench_traversal_test.go",
"doc.go",
"doc/tips.md",
"example_test.go",
"expand.go",
"expand_test.go",
"filter.go",
"filter_test.go",
"iteration.go",
"iteration_test.go",
"manipulation.go",
"manipulation_test.go",
"misc/git/pre-commit",
"property.go",
"property_test.go",
"query.go",
"query_test.go",
"testdata/gotesting.html",
"testdata/gowiki.html",
"testdata/metalreview.html",
"testdata/page.html",
"testdata/page2.html",
"testdata/page3.html",
"traversal.go",
"traversal_test.go",
"type.go",
"type_test.go",
"utilities.go",
"utilities_test.go",
},
},
{
path: "github.com/rsc/vgotest1",
version: "v0.0.0-20180219223237-a08abb797a67",
latest: true,
time: time.Date(2018, 02, 19, 22, 32, 37, 0, time.UTC),
},
}
var _modListTests = []struct {
path string
versions []string
}{
{
path: "github.com/rsc/vgotest1",
versions: []string{"v0.0.0", "v0.0.1", "v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3", "v1.1.0", "v2.0.0+incompatible"},
},
}
func TestFetchInfo(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
for _, mod := range _modInfoTests {
req := buildRequest(mod.path, mod.version, ".info")
rr, err := basicCheck(req)
if err != nil {
t.Error(err)
continue
}
// check return data
info := new(modfetch.RevInfo)
if err := json.Unmarshal(rr.Body.Bytes(), info); err != nil {
t.Errorf("package info is not recognized")
continue
}
if mod.version != info.Version {
t.Errorf("info.Version = %s, want %s", info.Version, mod.version)
}
if !mod.time.Equal(info.Time) {
t.Errorf("info.Time = %v, want %v", info.Time, mod.time)
}
}
}
func TestFetchModFile(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
for _, mod := range _modInfoTests {
if len(mod.gomod) == 0 {
continue
}
req := buildRequest(mod.path, mod.version, ".mod")
rr, err := basicCheck(req)
if err != nil {
t.Error(err)
continue
}
if data := rr.Body.String(); data != mod.gomod {
t.Errorf("repo.GoMod(%q) = %q, want %q", mod.version, data, mod.gomod)
}
}
}
func TestFetchZip(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
for _, mod := range _modInfoTests {
if len(mod.zip) == 0 {
continue
}
req := buildRequest(mod.path, mod.version, ".zip")
rr, err := basicCheck(req)
if err != nil {
t.Error(err)
continue
}
prefix := mod.path + "@" + mod.version + "/"
var names []string
data := rr.Body.Bytes() // ??
z, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
if err != nil {
t.Errorf("open %s's zip failed: %v", mod.path, err)
continue
}
for _, file := range z.File {
if !strings.HasPrefix(file.Name, prefix) {
t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
continue
}
names = append(names, file.Name[len(prefix):])
}
if !reflect.DeepEqual(names, mod.zip) {
t.Errorf("zip = %v\nwant %v\n", names, mod.zip)
}
}
}
func TestLatest(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
for _, mod := range _modInfoTests {
if !mod.latest {
continue
}
req := buildRequest(mod.path, "latest", "")
rr, err := basicCheck(req)
if err != nil {
t.Error(err)
continue
}
info := new(modfetch.RevInfo)
if err := json.Unmarshal(rr.Body.Bytes(), info); err != nil {
t.Errorf("package info is not recognized")
continue
}
if mod.version != info.Version {
t.Errorf("info.Version = %s, want %s", info.Version, mod.version)
}
if !mod.time.Equal(info.Time) {
t.Errorf("info.Time = %v, want %v", info.Time, mod.time)
}
}
}
func TestList(t *testing.T) {
for _, mod := range _modListTests {
req := buildRequest(mod.path, "", "")
rr, err := basicCheck(req)
if err != nil {
t.Error(err)
continue
}
modfetch.SortVersions(mod.versions)
if data := rr.Body.String(); strings.Join(mod.versions, "\n") != data {
t.Errorf("list not well,\n expected: %v\n, got: %v", mod.versions, strings.Split(data, "\n"))
}
}
}
func buildRequest(modPath, modVersion string, ext string) *http.Request {
modPath, _ = module.EncodePath(modPath)
modVersion, _ = module.EncodeVersion(modVersion)
url := "/" + modPath
switch modVersion {
case "":
url += "/@v/list"
case "latest":
url += "/@latest"
default:
url = url + "/@v/" + modVersion + ext
}
req, _ := http.NewRequest("GET", url, nil)
return req
}
func basicCheck(req *http.Request) (*httptest.ResponseRecorder, error) {
rr := httptest.NewRecorder()
_handle.ServeHTTP(rr, req)
// Check the status code is what we expect.
if status := rr.Code; status != http.StatusOK {
return nil, fmt.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
return rr, nil
}