internal/proxy,internal/fetch: create module zipfiles during test setup

All module zips inside internal/proxy/testdata were previously created
manually. They are now created automatically when tests are run.

Testdata for modules that were previoulsy inside internal/fetch/testdata
are moved to internal/proxy/testdata.

Tests inside internal/proxy and internal/fetch are updated to reflect
this changes.

Change-Id: I348fd4ebfe6c4ec0751945966984afc3859a2330
Reviewed-on: https://team-review.git.corp.google.com/c/golang/discovery/+/435777
Reviewed-by: Andrew Bonventre <andybons@google.com>
This commit is contained in:
Julie Qiu 2019-03-18 11:09:45 -04:00
Родитель dc7cd4ceb0
Коммит 31b7830d5d
44 изменённых файлов: 414 добавлений и 164 удалений

3
go.sum
Просмотреть файл

@ -113,6 +113,7 @@ github.com/duosecurity/duo_api_golang v0.0.0-20190107154727-539434bf0d45/go.mod
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.6.8/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@ -137,6 +138,7 @@ github.com/go-stomp/stomp v2.0.2+incompatible/go.mod h1:VqCtqNZv1226A1/79yh+rMiF
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gocql/gocql v0.0.0-20181117210152-33c0e89ca93a/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
github.com/gocql/gocql v0.0.0-20190122205811-30de9a1866a8/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/gddo v0.0.0-20181116215533-9bd4a3295021/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -271,6 +273,7 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b/go.mod h1:5MWrJXKRQyhQdUCF+vu6U5c4nQpg70vW3eHaU0/AYbU=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=

Просмотреть файл

@ -222,13 +222,12 @@ func containsFile(r *zip.Reader, expectedFile string) bool {
return false
}
// hasFilename checks if:
// (1) file is expectedFile, or
// (2) the name of file, without the base, is equal to expectedFile.
// It is case insensitive.
// hasFilename checks if file is expectedFile or if the name of file, without
// the base, is equal to expectedFile. It is case insensitive.
func hasFilename(file string, expectedFile string) bool {
base := filepath.Base(file)
return strings.EqualFold(base, expectedFile) ||
return strings.EqualFold(file, expectedFile) ||
strings.EqualFold(base, expectedFile) ||
strings.EqualFold(strings.TrimSuffix(base, filepath.Ext(base)), expectedFile)
}

Просмотреть файл

@ -9,8 +9,6 @@ import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"path/filepath"
@ -38,56 +36,6 @@ func structToString(i interface{}) string {
return b.String()
}
// zipFiles compresses the files inside dir files into a single zip archive
// file. filename is the output zip file's name.
func zipFiles(filename string, dir string) (func(), error) {
cleanup := func() { os.Remove(filename) }
newZipFile, err := os.Create(filename)
if err != nil {
return cleanup, fmt.Errorf("os.Create(%q): %v", filename, err)
}
defer newZipFile.Close()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
return cleanup, filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
fileToZip, err := os.Open(path)
if err != nil {
return fmt.Errorf("os.Open(%q): %v", path, err)
}
defer fileToZip.Close()
header, err := zip.FileInfoHeader(info)
if err != nil {
return fmt.Errorf("zipFileInfoHeader(%v): %v", info.Name(), err)
}
// Using FileInfoHeader() above only uses the basename of the file. If we want
// to preserve the folder structure we can overwrite this with the full path.
header.Name = strings.TrimPrefix(strings.TrimPrefix(path, dir), "/")
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return fmt.Errorf("zipWriter.CreateHeader(%+v): %v", header, err)
}
if _, err = io.Copy(writer, fileToZip); err != nil {
return fmt.Errorf("io.Copy(%v, %+v): %v", writer, fileToZip, err)
}
return nil
})
}
func TestFetchAndInsertVersion(t *testing.T) {
testCases := []struct {
name string
@ -114,8 +62,8 @@ func TestFetchAndInsertVersion(t *testing.T) {
teardownDB, db := postgres.SetupCleanDB(t)
defer teardownDB(t)
teardownProxyClient, client := proxy.SetupTestProxyClient(t)
defer teardownProxyClient(t)
teardownProxy, client := proxy.SetupTestProxy(t)
defer teardownProxy(t)
if err := FetchAndInsertVersion(test.name, test.version, client, db); err != nil {
t.Fatalf("FetchVersion(%q, %q, %v, %v): %v", test.name, test.version, client, db, err)
@ -247,6 +195,11 @@ func TestHasFilename(t *testing.T) {
expectedFile: "README",
want: false,
},
{
file: "my/module@v1.0.0/LICENSE",
expectedFile: "my/module@v1.0.0/LICENSE",
want: true,
},
} {
{
t.Run(test.file, func(t *testing.T) {
@ -290,42 +243,45 @@ func TestSeriesNameForModule(t *testing.T) {
func TestContainsFile(t *testing.T) {
for _, test := range []struct {
zip string
File string
Want bool
name, version, file string
want bool
}{
{
zip: "module.zip",
File: "README",
Want: true,
name: "my/module",
version: "v1.0.0",
file: "README",
want: true,
},
{
zip: "module.zip",
File: "LICENSE",
Want: false,
name: "my/module",
version: "v1.0.0",
file: "my/module@v1.0.0/LICENSE",
want: true,
},
{
zip: "empty.zip",
File: "README",
Want: false,
name: "empty/module",
version: "v1.0.0",
file: "README",
want: false,
},
{
zip: "empty.zip",
File: "LICENSE",
Want: false,
name: "empty/module",
version: "v1.0.0",
file: "LICENSE",
want: false,
},
} {
t.Run(test.zip, func(t *testing.T) {
name := filepath.Join("testdata/modules", test.zip)
rc, err := zip.OpenReader(name)
if err != nil {
t.Fatalf("zip.OpenReader(%q): %v", name, err)
}
defer rc.Close()
z := &rc.Reader
t.Run(test.name, func(t *testing.T) {
teardownProxy, client := proxy.SetupTestProxy(t)
defer teardownProxy(t)
if got := containsFile(z, test.File); got != test.Want {
t.Errorf("containsFile(%q, %q) = %t, want %t", name, test.File, got, test.Want)
reader, err := client.GetZip(test.name, test.version)
if err != nil {
t.Fatalf("client.GetZip(%q %q): %v", test.name, test.version, err)
}
if got := containsFile(reader, test.file); got != test.want {
t.Errorf("containsFile(%q, %q) = %t, want %t", fmt.Sprintf("%s %s", test.name, test.version), test.file, got, test.want)
}
})
}
@ -333,47 +289,44 @@ func TestContainsFile(t *testing.T) {
func TestExtractFile(t *testing.T) {
for _, test := range []struct {
zip string
file string
err error
name, version, file string
want []byte
err error
}{
{
zip: "module.zip",
file: "my/module@v1.0.0/README.md",
err: nil,
name: "my/module",
version: "v1.0.0",
file: "my/module@v1.0.0/README.md",
want: []byte("README FILE FOR TESTING."),
},
{
zip: "empty.zip",
file: "empty/nonexistent/README.md",
err: errors.New(`zip does not contain "README.md"`),
name: "empty/module",
version: "v1.0.0",
file: "empty/nonexistent/README.md",
err: errors.New(`zip does not contain "README.md"`),
},
} {
t.Run(test.zip, func(t *testing.T) {
rc, err := zip.OpenReader(filepath.Join("testdata/modules", test.zip))
if err != nil {
t.Fatalf("zip.OpenReader(%q): %v", test.zip, err)
}
defer rc.Close()
z := &rc.Reader
t.Run(test.file, func(t *testing.T) {
teardownProxy, client := proxy.SetupTestProxy(t)
defer teardownProxy(t)
got, err := extractFile(z, filepath.Base(test.file))
reader, err := client.GetZip(test.name, test.version)
if err != nil {
t.Fatalf("client.GetZip(%q, %q): %v", test.name, test.version, err)
}
got, err := extractFile(reader, filepath.Base(test.file))
if err != nil {
if test.err == nil || test.err.Error() != err.Error() {
t.Errorf("extractFile(%q, %q): \n %v, want \n %v",
test.zip, filepath.Base(test.file), err, test.err)
fmt.Sprintf("%q %q", test.name, test.version), filepath.Base(test.file), err, test.err)
} else {
return
}
}
f := filepath.Join("testdata/modules", test.file)
want, err := ioutil.ReadFile(f)
if err != nil {
t.Fatalf("ioutfil.ReadFile(%q) error: %v", f, err)
}
if !bytes.Equal(want, got) {
t.Errorf("extractFile(%q, %q) = %q, want %q", test.zip, test.file, got, want)
if !bytes.Equal(test.want, got) {
t.Errorf("extractFile(%q, %q) = %q, want %q", test.name, test.file, got, test.want)
}
})
}
@ -403,32 +356,32 @@ func TestExtractPackagesFromZip(t *testing.T) {
},
},
{
zip: "empty.zip",
name: "empty/module",
version: "v1.0.0",
packages: map[string]*internal.Package{},
},
} {
t.Run(test.name, func(t *testing.T) {
rc, err := zip.OpenReader(filepath.Join("testdata/modules", test.zip))
if err != nil {
t.Fatalf("zip.OpenReader(%q): %v", test.zip, err)
}
defer rc.Close()
z := &rc.Reader
teardownProxy, client := proxy.SetupTestProxy(t)
defer teardownProxy(t)
packages, err := extractPackagesFromZip(test.name, test.version, z)
reader, err := client.GetZip(test.name, test.version)
if err != nil {
t.Fatalf("client.GetZip(%q %q): %v", test.name, test.version, err)
}
packages, err := extractPackagesFromZip(test.name, test.version, reader)
if err != nil && len(test.packages) != 0 {
t.Fatalf("zipToPackages(%q, %q): %v", test.name, test.zip, err)
t.Fatalf("extractPackagesFromZip(%q, %q): %v", test.name, test.zip, err)
}
for _, got := range packages {
want, ok := test.packages[got.Name]
if !ok {
t.Errorf("zipToPackages(%q, %q) returned unexpected package: %q", test.name, test.zip, got.Name)
t.Errorf("extractPackagesFromZip(%q, %q) returned unexpected package: %q", test.name, test.zip, got.Name)
}
if want.Path != got.Path {
t.Errorf("zipToPackages(%q, %q) returned unexpected path for package %q: %q, want %q",
t.Errorf("extractPackagesFromZip(%q, %q) returned unexpected path for package %q: %q, want %q",
test.name, test.zip, got.Name, got.Path, want.Path)
}
@ -481,10 +434,10 @@ func TestDetectLicense(t *testing.T) {
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
testDir := filepath.Join("testdata/licenses", test.zipName)
cleanUpZip, err := zipFiles(testDir+".zip", testDir)
cleanUpZip, err := proxy.ZipFiles(testDir+".zip", testDir, "")
defer cleanUpZip()
if err != nil {
t.Fatalf("zipFiles(%q): %v", test.zipName, err)
t.Fatalf("proxy.ZipFiles(%q): %v", test.zipName, err)
}
if _, err := os.Stat(testDir + ".zip"); err != nil {

Двоичные данные
internal/fetch/testdata/modules/empty.zip поставляемый

Двоичный файл не отображается.

Двоичные данные
internal/fetch/testdata/modules/module.zip поставляемый

Двоичный файл не отображается.

Просмотреть файл

Просмотреть файл

@ -1 +0,0 @@
This README.md is used for testing.

Просмотреть файл

@ -23,8 +23,8 @@ func TestCleanURL(t *testing.T) {
}
func TestGetInfo(t *testing.T) {
teardownTestCase, client := SetupTestProxyClient(t)
defer teardownTestCase(t)
teardownProxy, client := SetupTestProxy(t)
defer teardownProxy(t)
name := "my/module"
version := "v1.0.0"
@ -44,8 +44,8 @@ func TestGetInfo(t *testing.T) {
}
func TestGetInfoVersionDoesNotExist(t *testing.T) {
teardownTestCase, client := SetupTestProxyClient(t)
defer teardownTestCase(t)
teardownProxy, client := SetupTestProxy(t)
defer teardownProxy(t)
name := "my/module"
version := "v3.0.0"
@ -56,8 +56,8 @@ func TestGetInfoVersionDoesNotExist(t *testing.T) {
}
func TestGetZip(t *testing.T) {
teardownTestCase, client := SetupTestProxyClient(t)
defer teardownTestCase(t)
teardownProxy, client := SetupTestProxy(t)
defer teardownProxy(t)
name := "my/module"
version := "v1.0.0"
@ -67,11 +67,11 @@ func TestGetZip(t *testing.T) {
}
expectedFiles := map[string]bool{
"my/": true,
"my/module@v1.0.0/": true,
"my/module@v1.0.0/LICENSE": true,
"my/module@v1.0.0/README.md": true,
"my/module@v1.0.0/go.mod": true,
"my/module@v1.0.0/LICENSE": true,
"my/module@v1.0.0/README.md": true,
"my/module@v1.0.0/go.mod": true,
"my/module@v1.0.0/foo/foo.go": true,
"my/module@v1.0.0/bar/bar.go": true,
}
if len(zipReader.File) != len(expectedFiles) {
t.Errorf("GetZip(%q, %q) returned number of files: got %d, want %d",
@ -88,8 +88,8 @@ func TestGetZip(t *testing.T) {
}
func TestGetZipNonExist(t *testing.T) {
teardownTestCase, client := SetupTestProxyClient(t)
defer teardownTestCase(t)
teardownProxy, client := SetupTestProxy(t)
defer teardownProxy(t)
name := "my/nonexistmodule"
version := "v1.0.0"

Просмотреть файл

@ -5,37 +5,45 @@
package proxy
import (
"archive/zip"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
// SetupTestProxyClient creates a module proxy for testing using static files
// SetupTestProxy creates a module proxy for testing using static files
// stored in internal/proxy/testdata/modproxy/proxy. It returns a function
// for tearing down the proxy after the test is completed and a Client for
// interacting with the test proxy. The following module versions are supported
// by the proxy: (1) my/module v1.0.0 (2) my/module v1.1.0 (3) my/module v1.1.1
// (4) my/module/v2 v2.0.0.
func SetupTestProxyClient(t *testing.T) (func(t *testing.T), *Client) {
// interacting with the test proxy.
func SetupTestProxy(t *testing.T) (func(t *testing.T), *Client) {
t.Helper()
proxyDataDir := "../proxy/testdata/modproxy/proxy"
proxyDataDir := "../proxy/testdata/modproxy"
absPath, err := filepath.Abs(proxyDataDir)
if err != nil {
t.Fatalf("filepath.Abs(%q): %v", proxyDataDir, err)
}
p := httptest.NewServer(http.FileServer(http.Dir(absPath)))
p := httptest.NewServer(http.FileServer(http.Dir(fmt.Sprintf("%s/proxy", absPath))))
client := New(p.URL)
expectedVersions := [][]string{
for _, v := range [][]string{
[]string{"my/module", "v1.0.0"},
[]string{"my/module", "v1.1.0"},
[]string{"my/module", "v1.1.1"},
[]string{"my/module/v2", "v2.0.0"},
}
[]string{"empty/module", "v1.0.0"},
[]string{"rsc.io/quote", "v1.5.2"},
[]string{"rsc.io/quote/v2", "v2.0.1"},
} {
zipfile := fmt.Sprintf("%s/proxy/%s/@v/%s.zip", absPath, v[0], v[1])
zipDataDir := fmt.Sprintf("%s/modules/%s@%s", absPath, v[0], v[1])
if _, err := ZipFiles(zipfile, zipDataDir, fmt.Sprintf("%s@%s", v[0], v[1])); err != nil {
t.Fatalf("proxy.ZipFiles(%q): %v", zipDataDir, err)
}
for _, v := range expectedVersions {
if _, err := client.GetInfo(v[0], v[1]); err != nil {
t.Fatalf("client.GetInfo(%q, %q): %v", v[0], v[1], err)
}
@ -46,3 +54,56 @@ func SetupTestProxyClient(t *testing.T) (func(t *testing.T), *Client) {
}
return fn, client
}
// ZipFiles compresses the files inside dir into a single zip archive file.
// zipfile is the output zip file's name. Files inside zipfile will all have
// prefix moduleDir. ZipFiles return a function to cleanup files that were
// created.
func ZipFiles(zipfile, dir, moduleDir string) (func() error, error) {
cleanup := func() error {
os.Remove(zipfile)
}
newZipFile, err := os.Create(zipfile)
if err != nil {
return cleanup, fmt.Errorf("os.Create(%q): %v", zipfile, err)
}
defer newZipFile.Close()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
return cleanup, filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
fileToZip, err := os.Open(path)
if err != nil {
return fmt.Errorf("os.Open(%q): %v", path, err)
}
defer fileToZip.Close()
header, err := zip.FileInfoHeader(info)
if err != nil {
return fmt.Errorf("zipFileInfoHeader(%v): %v", info.Name(), err)
}
// Using FileInfoHeader() above only uses the basename of the file. If we want
// to preserve the folder structure we can overwrite this with the full path.
header.Name = strings.TrimPrefix(strings.TrimPrefix(path, strings.TrimSuffix(dir, moduleDir)), "/")
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return fmt.Errorf("zipWriter.CreateHeader(%+v): %v", header, err)
}
if _, err = io.Copy(writer, fileToZip); err != nil {
return fmt.Errorf("io.Copy(%v, %+v): %v", writer, fileToZip, err)
}
return nil
})
}

Просмотреть файл

@ -4,7 +4,12 @@
package foo
// Foo returns the string "foo".
func Foo() string {
return "foo"
import (
"fmt"
"my/module/bar"
)
// FooBar returns the string "foo bar".
func FooBar() string {
return fmt.Sprintf("foo %s", bar.Bar())
}

Просмотреть файл

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Просмотреть файл

@ -0,0 +1,4 @@
This package collects pithy sayings.
It's part of a demonstration of
[package versioning in Go](https://research.swtch.com/vgo1).

Просмотреть файл

@ -0,0 +1,3 @@
module rsc.io/quote/v2
require rsc.io/sampler v1.3.0

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package quote collects pithy sayings.
package quote // import "rsc.io/quote"
import "rsc.io/sampler"
// Hello returns a greeting.
func HelloV2() string {
return sampler.Hello()
}
// Glass returns a useful phrase for world travelers.
func GlassV2() string {
// See http://www.oocities.org/nodotus/hbglass.html.
return "I can eat glass and it doesn't hurt me."
}
// Go returns a Go proverb.
func GoV2() string {
return "Don't communicate by sharing memory, share memory by communicating."
}
// Opt returns an optimization truth.
func OptV2() string {
// Wisdom from ken.
return "If a program is too slow, it must have a loop."
}

Просмотреть файл

@ -0,0 +1,42 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quote
import (
"os"
"testing"
)
func init() {
os.Setenv("LC_ALL", "en")
}
func TestHello(t *testing.T) {
hello := "Hello, world."
if out := Hello(); out != hello {
t.Errorf("Hello() = %q, want %q", out, hello)
}
}
func TestGlass(t *testing.T) {
glass := "I can eat glass and it doesn't hurt me."
if out := Glass(); out != glass {
t.Errorf("Glass() = %q, want %q", out, glass)
}
}
func TestGo(t *testing.T) {
go1 := "Don't communicate by sharing memory, share memory by communicating."
if out := Go(); out != go1 {
t.Errorf("Go() = %q, want %q", out, go1)
}
}
func TestOpt(t *testing.T) {
opt := "If a program is too slow, it must have a loop."
if out := Opt(); out != opt {
t.Errorf("Opt() = %q, want %q", out, opt)
}
}

Просмотреть файл

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Просмотреть файл

@ -0,0 +1,4 @@
This package collects pithy sayings.
It's part of a demonstration of
[package versioning in Go](https://research.swtch.com/vgo1).

Просмотреть файл

@ -0,0 +1,11 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package buggy
import "testing"
func Test(t *testing.T) {
t.Fatal("buggy!")
}

Просмотреть файл

@ -0,0 +1,3 @@
module "rsc.io/quote"
require "rsc.io/sampler" v1.3.0

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package quote collects pithy sayings.
package quote // import "rsc.io/quote"
import "rsc.io/sampler"
// Hello returns a greeting.
func Hello() string {
return sampler.Hello()
}
// Glass returns a useful phrase for world travelers.
func Glass() string {
// See http://www.oocities.org/nodotus/hbglass.html.
return "I can eat glass and it doesn't hurt me."
}
// Go returns a Go proverb.
func Go() string {
return "Don't communicate by sharing memory, share memory by communicating."
}
// Opt returns an optimization truth.
func Opt() string {
// Wisdom from ken.
return "If a program is too slow, it must have a loop."
}

Просмотреть файл

@ -0,0 +1,42 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quote
import (
"os"
"testing"
)
func init() {
os.Setenv("LC_ALL", "en")
}
func TestHello(t *testing.T) {
hello := "Hello, world."
if out := Hello(); out != hello {
t.Errorf("Hello() = %q, want %q", out, hello)
}
}
func TestGlass(t *testing.T) {
glass := "I can eat glass and it doesn't hurt me."
if out := Glass(); out != glass {
t.Errorf("Glass() = %q, want %q", out, glass)
}
}
func TestGo(t *testing.T) {
go1 := "Don't communicate by sharing memory, share memory by communicating."
if out := Go(); out != go1 {
t.Errorf("Go() = %q, want %q", out, go1)
}
}
func TestOpt(t *testing.T) {
opt := "If a program is too slow, it must have a loop."
if out := Opt(); out != opt {
t.Errorf("Opt() = %q, want %q", out, opt)
}
}

1
internal/proxy/testdata/modproxy/proxy/empty/module/@v/list поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
v1.0.0

Просмотреть файл

@ -0,0 +1,4 @@
{
"Version": "v1.0.0",
"Time": "2019-01-30T00:00:00Z"
}

Просмотреть файл

@ -0,0 +1,3 @@
module empty/module
go 1.12

Двоичные данные
internal/proxy/testdata/modproxy/proxy/empty/module/@v/v1.0.0.zip поставляемый Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -1,3 +0,0 @@
module my/module
go 1.12

Двоичные данные
internal/proxy/testdata/modproxy/proxy/my/module/@v/v1.0.0.zip поставляемый

Двоичный файл не отображается.

Просмотреть файл

@ -1 +0,0 @@
v2.0.0

Просмотреть файл

@ -1,6 +0,0 @@
{
"Version": "v2.0.0",
"Name": "my/module/v2",
"Short": "v0.8.0",
"Time": "2019-02-08T00:41:07Z"
}

Просмотреть файл

@ -1 +0,0 @@
module my/module/v2

Двоичные данные
internal/proxy/testdata/modproxy/proxy/my/module/v2/@v/v2.0.0.zip поставляемый

Двоичный файл не отображается.

1
internal/proxy/testdata/modproxy/proxy/rsc.io/quote/@v/list поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
v1.5.2

Просмотреть файл

@ -0,0 +1 @@
{"Version":"v1.5.2","Time":"2018-02-14T15:44:20Z"}

Просмотреть файл

@ -0,0 +1,3 @@
module "rsc.io/quote"
require "rsc.io/sampler" v1.3.0

Двоичные данные
internal/proxy/testdata/modproxy/proxy/rsc.io/quote/@v/v1.5.2.zip поставляемый Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1 @@
v2.0.1

Просмотреть файл

@ -0,0 +1 @@
{"Version":"v2.0.1","Time":"2018-07-09T16:25:34Z"}

Просмотреть файл

@ -0,0 +1,3 @@
module rsc.io/quote/v2
require rsc.io/sampler v1.3.0

Двоичные данные
internal/proxy/testdata/modproxy/proxy/rsc.io/quote/v2/@v/v2.0.1.zip поставляемый Normal file

Двоичный файл не отображается.