stats test, add/remove torrent handlers, init batter driver

This commit is contained in:
Jimmy Zelinskie 2013-08-28 23:44:45 -04:00
parent 107ec1dd15
commit ecbedf4b89
8 changed files with 166 additions and 83 deletions

View file

@ -41,7 +41,7 @@ func (d *driver) New(conf *config.DataStore) cache.Pool {
func makeDialFunc(conf *config.DataStore) func() (redis.Conn, error) { func makeDialFunc(conf *config.DataStore) func() (redis.Conn, error) {
return func() (conn redis.Conn, err error) { return func() (conn redis.Conn, err error) {
conn, err = redis.Dial(conf.Network, conf.Addr) conn, err = redis.Dial(conf.Network, conf.Host+":"+conf.Port)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -31,7 +31,8 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
type DataStore struct { type DataStore struct {
Driver string `json:"driver"` Driver string `json:"driver"`
Network string `json:"network` Network string `json:"network`
Addr string `json:"addr"` Host string `json:"host"`
Port string `json:"port"`
Username string `json:"user"` Username string `json:"user"`
Password string `json:"pass"` Password string `json:"pass"`
Schema string `json:"schema,omitempty"` Schema string `json:"schema,omitempty"`

View file

@ -5,95 +5,25 @@
package config package config
import ( import (
"bufio" "bytes"
"io/ioutil"
"os" "os"
"path/filepath"
"strings"
"testing" "testing"
) )
var exampleJson = `{ func TestOpenConfig(t *testing.T) {
if _, err := Open(os.ExpandEnv("$GOPATH/src/github.com/pushrax/chihaya/config/example.json")); err != nil {
"network": "tcp",
"addr": ":34000",
"pub_addr": "tcp://*:34001",
"cache": {
"driver": "redis",
"addr": "127.0.0.1:6379",
"user": "root",
"pass": "",
"prefix": "test:",
"max_idle_conn": 3,
"idle_timeout": "240s"
},
"storage": {
"driver": "batter",
"addr": "127.0.0.1:5432",
"user": "postgres",
"pass": ""
},
"private": true,
"freeleech": false,
"announce": "30m",
"min_announce": "15m",
"read_timeout": "20s",
"default_num_want": 50,
"tx_retries": 3
}`
func TestNewConfig(t *testing.T) {
if _, err := newConfig(strings.NewReader(exampleJson)); err != nil {
t.Error(err) t.Error(err)
} }
} }
func writeAndOpenJsonTest(t *testing.T, fn string) { func TestNewConfig(t *testing.T) {
expandFn := os.ExpandEnv(fn) contents, err := ioutil.ReadFile(os.ExpandEnv("$GOPATH/src/github.com/pushrax/chihaya/config/example.json"))
// Write JSON to relative path, clean up
tfile, ferr := os.Create(expandFn)
// Remove failure not counted as error
defer os.Remove(expandFn)
if ferr != nil {
t.Fatal("Failed to create %s. Error: %v", expandFn, ferr)
}
tWriter := bufio.NewWriter(tfile)
cw, err := tWriter.WriteString(exampleJson)
if err != nil { if err != nil {
t.Fatal("Failed to write json to config file. %v", err) t.Error(err)
} }
if cw < len(exampleJson) { buff := bytes.NewBuffer(contents)
t.Error("Incorrect length of config file written %v vs. %v", cw, len(exampleJson)) if _, err := newConfig(buff); err != nil {
} t.Error(err)
fErr := tWriter.Flush()
if fErr != nil {
t.Error("Flush error: %v", fErr)
}
_, oErr := Open(fn)
if oErr != nil {
t.Error("Open error: %v", oErr)
}
}
// These implcitly require the test program have
// read/write/delete file system permissions
func TestOpenCurDir(t *testing.T) {
if !testing.Short() {
writeAndOpenJsonTest(t, "testConfig.json")
} else {
t.Log("Write/Read file test skipped")
}
}
func TestOpenAbsEnvPath(t *testing.T) {
if !testing.Short() {
writeAndOpenJsonTest(t, filepath.Join(os.TempDir(), "testConfig.json"))
} else {
t.Log("Write/Read file test skipped")
} }
} }

36
config/example.json Normal file
View file

@ -0,0 +1,36 @@
{
"network": "tcp",
"addr": ":80",
"cache": {
"driver": "redis",
"host": "127.0.0.1",
"port": "6379",
"user": "root",
"pass": "",
"prefix": "test:",
"max_idle_conn": 3,
"idle_timeout": "240s"
},
"storage": {
"driver": "batter",
"host": "127.0.0.1",
"port": "5432",
"user": "postgres",
"pass": ""
},
"private": true,
"freeleech": false,
"announce": "30m",
"min_announce": "15m",
"read_timeout": "20s",
"default_num_want": 50,
"tx_retries": 3
}

17
server/addremove.go Normal file
View file

@ -0,0 +1,17 @@
// Copyright 2013 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package server
import (
"net/http"
)
func (s Server) serveAdd(w http.ResponseWriter, r *http.Request) {
return
}
func (s Server) serveRemove(w http.ResponseWriter, r *http.Request) {
return
}

View file

@ -96,9 +96,16 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer s.waitgroup.Done() defer s.waitgroup.Done()
defer atomic.AddInt64(&s.deltaRequests, 1) defer atomic.AddInt64(&s.deltaRequests, 1)
if r.URL.Path == "/stats" { switch r.URL.Path {
case "/stats":
s.serveStats(w, r) s.serveStats(w, r)
return return
case "/add":
s.serveAdd(w, r)
return
case "/remove":
s.serveRemove(w, r)
return
} }
_, action := path.Split(r.URL.Path) _, action := path.Split(r.URL.Path)

40
server/stats_test.go Normal file
View file

@ -0,0 +1,40 @@
// Copyright 2013 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package server
import (
"errors"
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/pushrax/chihaya/config"
_ "github.com/pushrax/chihaya/cache/redis"
_ "github.com/pushrax/chihaya/storage/batter"
)
func TestStats(t *testing.T) {
testConfig, err := config.Open(os.ExpandEnv("$GOPATH/src/github.com/pushrax/chihaya/config/example.json"))
if err != nil {
t.Error(err)
}
fmt.Println(testConfig)
s, err := New(testConfig)
if err != nil {
t.Error(err)
}
r, err := http.NewRequest("GET", "127.0.0.1:80/stats", nil)
if err != nil {
t.Error(err)
}
w := httptest.NewRecorder()
s.serveStats(w, r)
if w.Code != 200 {
t.Error(errors.New("/stats did not return HTTP 200"))
}
}

52
storage/batter/batter.go Normal file
View file

@ -0,0 +1,52 @@
// Copyright 2013 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
// Package batter provides a driver for a BitTorrent tracker to interface
// with the postgres database used by batter (github.com/wafflesfm/batter).
package batter
import (
"database/sql"
"fmt"
"github.com/pushrax/chihaya/config"
"github.com/pushrax/chihaya/models"
"github.com/pushrax/chihaya/storage"
_ "github.com/bmizerany/pq"
)
type driver struct{}
func (d *driver) New(conf *config.DataStore) storage.Conn {
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s",
conf.Host,
conf.Port,
conf.Username,
conf.Password,
conf.Schema,
)
db, err := sql.Open("postgres", dsn)
if err != nil {
panic("batter: failed to open connection to postgres")
}
return &Conn{db}
}
type Conn struct {
*sql.DB
}
func (c *Conn) UpdateTorrents(t []models.Torrent) error {
return nil
}
func (c *Conn) UpdateUsers(u []models.User) error {
return nil
}
func init() {
storage.Register("batter", &driver{})
}