mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-11-27 14:40:18 +01:00
cb6e5cb0c7
* use dep for vendoring * lets encrypt * moved web to transfer.sh-web repo * single command install * added first tests
274 lines
7.3 KiB
Go
274 lines
7.3 KiB
Go
// Copyright 2013 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 or at
|
|
// https://developers.google.com/open-source/licenses/bsd.
|
|
|
|
package database
|
|
|
|
import (
|
|
"math"
|
|
"reflect"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/garyburd/redigo/redis"
|
|
"golang.org/x/net/context"
|
|
"google.golang.org/appengine/aetest"
|
|
|
|
"github.com/golang/gddo/doc"
|
|
)
|
|
|
|
func newDB(t *testing.T) *Database {
|
|
p := redis.NewPool(func() (redis.Conn, error) {
|
|
c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, err = c.Do("SELECT", "9")
|
|
if err != nil {
|
|
c.Close()
|
|
return nil, err
|
|
}
|
|
return c, nil
|
|
}, 1)
|
|
|
|
c := p.Get()
|
|
defer c.Close()
|
|
n, err := redis.Int(c.Do("DBSIZE"))
|
|
if n != 0 || err != nil {
|
|
t.Errorf("DBSIZE returned %d, %v", n, err)
|
|
}
|
|
return &Database{Pool: p}
|
|
}
|
|
|
|
func closeDB(db *Database) {
|
|
c := db.Pool.Get()
|
|
c.Do("FLUSHDB")
|
|
c.Close()
|
|
}
|
|
|
|
func TestPutGet(t *testing.T) {
|
|
var nextCrawl = time.Unix(time.Now().Add(time.Hour).Unix(), 0).UTC()
|
|
ctx, done, err := aetest.NewContext()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer done()
|
|
bgCtx = func() context.Context {
|
|
return ctx
|
|
}
|
|
|
|
db := newDB(t)
|
|
defer closeDB(db)
|
|
pdoc := &doc.Package{
|
|
ImportPath: "github.com/user/repo/foo/bar",
|
|
Name: "bar",
|
|
Synopsis: "hello",
|
|
ProjectRoot: "github.com/user/repo",
|
|
ProjectName: "foo",
|
|
Updated: time.Now().Add(-time.Hour),
|
|
Imports: []string{"C", "errors", "github.com/user/repo/foo/bar"}, // self import for testing convenience.
|
|
}
|
|
if err := db.Put(pdoc, nextCrawl, false); err != nil {
|
|
t.Errorf("db.Put() returned error %v", err)
|
|
}
|
|
if err := db.Put(pdoc, time.Time{}, false); err != nil {
|
|
t.Errorf("second db.Put() returned error %v", err)
|
|
}
|
|
|
|
actualPdoc, actualSubdirs, actualCrawl, err := db.Get("github.com/user/repo/foo/bar")
|
|
if err != nil {
|
|
t.Fatalf("db.Get(.../foo/bar) returned %v", err)
|
|
}
|
|
if len(actualSubdirs) != 0 {
|
|
t.Errorf("db.Get(.../foo/bar) returned subdirs %v, want none", actualSubdirs)
|
|
}
|
|
if !reflect.DeepEqual(actualPdoc, pdoc) {
|
|
t.Errorf("db.Get(.../foo/bar) returned doc %v, want %v", actualPdoc, pdoc)
|
|
}
|
|
if !nextCrawl.Equal(actualCrawl) {
|
|
t.Errorf("db.Get(.../foo/bar) returned crawl %v, want %v", actualCrawl, nextCrawl)
|
|
}
|
|
|
|
before := time.Now().Unix()
|
|
if err := db.BumpCrawl(pdoc.ProjectRoot); err != nil {
|
|
t.Errorf("db.BumpCrawl() returned %v", err)
|
|
}
|
|
after := time.Now().Unix()
|
|
|
|
_, _, actualCrawl, _ = db.Get("github.com/user/repo/foo/bar")
|
|
if actualCrawl.Unix() < before || after < actualCrawl.Unix() {
|
|
t.Errorf("actualCrawl=%v, expect value between %v and %v", actualCrawl.Unix(), before, after)
|
|
}
|
|
|
|
// Popular
|
|
|
|
if err := db.IncrementPopularScore(pdoc.ImportPath); err != nil {
|
|
t.Errorf("db.IncrementPopularScore() returned %v", err)
|
|
}
|
|
|
|
// Get "-"
|
|
|
|
actualPdoc, _, _, err = db.Get("-")
|
|
if err != nil {
|
|
t.Fatalf("db.Get(-) returned %v", err)
|
|
}
|
|
if !reflect.DeepEqual(actualPdoc, pdoc) {
|
|
t.Errorf("db.Get(-) returned doc %v, want %v", actualPdoc, pdoc)
|
|
}
|
|
|
|
actualPdoc, actualSubdirs, _, err = db.Get("github.com/user/repo/foo")
|
|
if err != nil {
|
|
t.Fatalf("db.Get(.../foo) returned %v", err)
|
|
}
|
|
if actualPdoc != nil {
|
|
t.Errorf("db.Get(.../foo) returned doc %v, want %v", actualPdoc, nil)
|
|
}
|
|
expectedSubdirs := []Package{{Path: "github.com/user/repo/foo/bar", Synopsis: "hello"}}
|
|
if !reflect.DeepEqual(actualSubdirs, expectedSubdirs) {
|
|
t.Errorf("db.Get(.../foo) returned subdirs %v, want %v", actualSubdirs, expectedSubdirs)
|
|
}
|
|
actualImporters, err := db.Importers("github.com/user/repo/foo/bar")
|
|
if err != nil {
|
|
t.Fatalf("db.Importers() returned error %v", err)
|
|
}
|
|
expectedImporters := []Package{{Path: "github.com/user/repo/foo/bar", Synopsis: "hello"}}
|
|
if !reflect.DeepEqual(actualImporters, expectedImporters) {
|
|
t.Errorf("db.Importers() = %v, want %v", actualImporters, expectedImporters)
|
|
}
|
|
actualImports, err := db.Packages(pdoc.Imports)
|
|
if err != nil {
|
|
t.Fatalf("db.Imports() returned error %v", err)
|
|
}
|
|
for i := range actualImports {
|
|
if actualImports[i].Path == "C" {
|
|
actualImports[i].Synopsis = ""
|
|
}
|
|
}
|
|
expectedImports := []Package{
|
|
{Path: "C", Synopsis: ""},
|
|
{Path: "errors", Synopsis: ""},
|
|
{Path: "github.com/user/repo/foo/bar", Synopsis: "hello"},
|
|
}
|
|
if !reflect.DeepEqual(actualImports, expectedImports) {
|
|
t.Errorf("db.Imports() = %v, want %v", actualImports, expectedImports)
|
|
}
|
|
importerCount, _ := db.ImporterCount("github.com/user/repo/foo/bar")
|
|
if importerCount != 1 {
|
|
t.Errorf("db.ImporterCount() = %d, want %d", importerCount, 1)
|
|
}
|
|
if err := db.Delete("github.com/user/repo/foo/bar"); err != nil {
|
|
t.Errorf("db.Delete() returned error %v", err)
|
|
}
|
|
|
|
db.Query("bar")
|
|
|
|
if err := db.Put(pdoc, time.Time{}, false); err != nil {
|
|
t.Errorf("db.Put() returned error %v", err)
|
|
}
|
|
|
|
if err := db.Block("github.com/user/repo"); err != nil {
|
|
t.Errorf("db.Block() returned error %v", err)
|
|
}
|
|
|
|
blocked, err := db.IsBlocked("github.com/user/repo/foo/bar")
|
|
if !blocked || err != nil {
|
|
t.Errorf("db.IsBlocked(github.com/user/repo/foo/bar) returned %v, %v, want true, nil", blocked, err)
|
|
}
|
|
|
|
blocked, err = db.IsBlocked("github.com/foo/bar")
|
|
if blocked || err != nil {
|
|
t.Errorf("db.IsBlocked(github.com/foo/bar) returned %v, %v, want false, nil", blocked, err)
|
|
}
|
|
|
|
c := db.Pool.Get()
|
|
defer c.Close()
|
|
c.Send("DEL", "maxQueryId")
|
|
c.Send("DEL", "maxPackageId")
|
|
c.Send("DEL", "block")
|
|
c.Send("DEL", "popular:0")
|
|
c.Send("DEL", "newCrawl")
|
|
keys, err := redis.Values(c.Do("HKEYS", "ids"))
|
|
for _, key := range keys {
|
|
t.Errorf("unexpected id %s", key)
|
|
}
|
|
keys, err = redis.Values(c.Do("KEYS", "*"))
|
|
for _, key := range keys {
|
|
t.Errorf("unexpected key %s", key)
|
|
}
|
|
}
|
|
|
|
const epsilon = 0.000001
|
|
|
|
func TestPopular(t *testing.T) {
|
|
db := newDB(t)
|
|
defer closeDB(db)
|
|
c := db.Pool.Get()
|
|
defer c.Close()
|
|
|
|
// Add scores for packages. On each iteration, add half-life to time and
|
|
// divide the score by two. All packages should have the same score.
|
|
|
|
now := time.Now()
|
|
score := float64(4048)
|
|
for id := 12; id >= 0; id-- {
|
|
path := "github.com/user/repo/p" + strconv.Itoa(id)
|
|
c.Do("HSET", "ids", path, id)
|
|
err := db.incrementPopularScoreInternal(path, score, now)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
now = now.Add(popularHalfLife)
|
|
score /= 2
|
|
}
|
|
|
|
values, _ := redis.Values(c.Do("ZRANGE", "popular", "0", "100000", "WITHSCORES"))
|
|
if len(values) != 26 {
|
|
t.Fatalf("Expected 26 values, got %d", len(values))
|
|
}
|
|
|
|
// Check for equal scores.
|
|
score, err := redis.Float64(values[1], nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for i := 3; i < len(values); i += 2 {
|
|
s, _ := redis.Float64(values[i], nil)
|
|
if math.Abs(score-s)/score > epsilon {
|
|
t.Errorf("Bad score, score[1]=%g, score[%d]=%g", score, i, s)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCounter(t *testing.T) {
|
|
db := newDB(t)
|
|
defer closeDB(db)
|
|
|
|
const key = "127.0.0.1"
|
|
|
|
now := time.Now()
|
|
n, err := db.incrementCounterInternal(key, 1, now)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if math.Abs(n-1.0) > epsilon {
|
|
t.Errorf("1: got n=%g, want 1", n)
|
|
}
|
|
n, err = db.incrementCounterInternal(key, 1, now)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if math.Abs(n-2.0)/2.0 > epsilon {
|
|
t.Errorf("2: got n=%g, want 2", n)
|
|
}
|
|
now = now.Add(counterHalflife)
|
|
n, err = db.incrementCounterInternal(key, 1, now)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if math.Abs(n-2.0)/2.0 > epsilon {
|
|
t.Errorf("3: got n=%g, want 2", n)
|
|
}
|
|
}
|