Merge pull request #347 from sosedoff/specs-refactor
Specs refactor and tweaks
This commit is contained in:
commit
d72f1c85c1
12
Godeps/Godeps.json
generated
12
Godeps/Godeps.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "github.com/sosedoff/pgweb",
|
"ImportPath": "github.com/sosedoff/pgweb",
|
||||||
"GoVersion": "go1.9",
|
"GoVersion": "go1.10",
|
||||||
"GodepVersion": "v79",
|
"GodepVersion": "v79",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./..."
|
"./..."
|
||||||
@ -112,6 +112,16 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "gopkg.in/yaml.v2",
|
"ImportPath": "gopkg.in/yaml.v2",
|
||||||
"Rev": "a5b47d31c556af34a302ce5d659e6fea44d90de0"
|
"Rev": "a5b47d31c556af34a302ce5d659e6fea44d90de0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew",
|
||||||
|
"Comment": "v1.1.3",
|
||||||
|
"Rev": "f390dcf405f7b83c997eac1b06768bb9f44dec18"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib",
|
||||||
|
"Comment": "v1.1.3",
|
||||||
|
"Rev": "f390dcf405f7b83c997eac1b06768bb9f44dec18"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ func initClient() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initOptions() {
|
func initOptions() {
|
||||||
err := command.ParseOptions()
|
opts, err := command.ParseOptions(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case *flags.Error:
|
case *flags.Error:
|
||||||
@ -104,8 +104,8 @@ func initOptions() {
|
|||||||
}
|
}
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
command.Opts = opts
|
||||||
options = command.Opts
|
options = opts
|
||||||
|
|
||||||
if options.Version {
|
if options.Version {
|
||||||
printVersion()
|
printVersion()
|
||||||
|
@ -367,7 +367,13 @@ func (client *Client) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) IsIdle() bool {
|
func (client *Client) IsIdle() bool {
|
||||||
return time.Since(client.lastQueryTime).Minutes() > command.Opts.ConnectionIdleTimeout
|
mins := int(time.Since(client.lastQueryTime).Minutes())
|
||||||
|
|
||||||
|
if command.Opts.ConnectionIdleTimeout > 0 {
|
||||||
|
return mins >= command.Opts.ConnectionIdleTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch all rows as strings for a single column
|
// Fetch all rows as strings for a single column
|
||||||
|
@ -2,12 +2,16 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/sosedoff/pgweb/pkg/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -43,6 +47,11 @@ func getVar(name, def string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initVars() {
|
func initVars() {
|
||||||
|
// We need to load default options to make sure all stuff works
|
||||||
|
if err := command.SetDefaultOptions(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
serverHost = getVar("PGHOST", "localhost")
|
serverHost = getVar("PGHOST", "localhost")
|
||||||
serverPort = getVar("PGPORT", "5432")
|
serverPort = getVar("PGPORT", "5432")
|
||||||
serverUser = getVar("PGUSER", "postgres")
|
serverUser = getVar("PGUSER", "postgres")
|
||||||
@ -148,6 +157,21 @@ func test_NewClientFromUrl2(t *testing.T) {
|
|||||||
assert.Equal(t, url, client.ConnectionString)
|
assert.Equal(t, url, client.ConnectionString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_ClientIdleTime(t *testing.T) {
|
||||||
|
examples := map[time.Time]bool{
|
||||||
|
time.Now(): false, // Current time
|
||||||
|
time.Now().Add(time.Minute * -30): false, // 30 minutes ago
|
||||||
|
time.Now().Add(time.Minute * -240): true, // 240 minutes ago
|
||||||
|
time.Now().Add(time.Minute * 30): false, // 30 minutes in future
|
||||||
|
time.Now().Add(time.Minute * 128): false, // 128 minutes in future
|
||||||
|
}
|
||||||
|
|
||||||
|
for ts, expected := range examples {
|
||||||
|
testClient.lastQueryTime = ts
|
||||||
|
assert.Equal(t, expected, testClient.IsIdle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func test_Test(t *testing.T) {
|
func test_Test(t *testing.T) {
|
||||||
assert.Equal(t, nil, testClient.Test())
|
assert.Equal(t, nil, testClient.Test())
|
||||||
}
|
}
|
||||||
@ -367,6 +391,7 @@ func TestAll(t *testing.T) {
|
|||||||
setupClient()
|
setupClient()
|
||||||
|
|
||||||
test_NewClientFromUrl(t)
|
test_NewClientFromUrl(t)
|
||||||
|
test_ClientIdleTime(t)
|
||||||
test_Test(t)
|
test_Test(t)
|
||||||
test_Info(t)
|
test_Info(t)
|
||||||
test_Activity(t)
|
test_Activity(t)
|
||||||
|
@ -35,60 +35,71 @@ type Options struct {
|
|||||||
ConnectToken string `long:"connect-token" description:"Authentication token for the third-party connect backend"`
|
ConnectToken string `long:"connect-token" description:"Authentication token for the third-party connect backend"`
|
||||||
ConnectHeaders string `long:"connect-headers" description:"List of headers to pass to the connect backend"`
|
ConnectHeaders string `long:"connect-headers" description:"List of headers to pass to the connect backend"`
|
||||||
DisableConnectionIdleTimeout bool `long:"no-idle-timeout" description:"Disable connection idle timeout" default:"false"`
|
DisableConnectionIdleTimeout bool `long:"no-idle-timeout" description:"Disable connection idle timeout" default:"false"`
|
||||||
ConnectionIdleTimeout float64 `long:"idle-timeout" description:"Set connection idle timeout in minutes" default:"180"`
|
ConnectionIdleTimeout int `long:"idle-timeout" description:"Set connection idle timeout in minutes" default:"180"`
|
||||||
Cors bool `long:"cors" description:"Enable Cross-Origin Resource Sharing (CORS)" default:"false"`
|
Cors bool `long:"cors" description:"Enable Cross-Origin Resource Sharing (CORS)" default:"false"`
|
||||||
CorsOrigin string `long:"cors-origin" description:"Allowed CORS origins" default:"*"`
|
CorsOrigin string `long:"cors-origin" description:"Allowed CORS origins" default:"*"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var Opts Options
|
var Opts Options
|
||||||
|
|
||||||
func ParseOptions() error {
|
func ParseOptions(args []string) (Options, error) {
|
||||||
_, err := flags.ParseArgs(&Opts, os.Args)
|
var opts = Options{}
|
||||||
|
|
||||||
|
_, err := flags.ParseArgs(&opts, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return opts, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if Opts.Url == "" {
|
if opts.Url == "" {
|
||||||
Opts.Url = os.Getenv("DATABASE_URL")
|
opts.Url = os.Getenv("DATABASE_URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("SESSIONS") != "" {
|
if os.Getenv("SESSIONS") != "" {
|
||||||
Opts.Sessions = true
|
opts.Sessions = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("LOCK_SESSION") != "" {
|
if os.Getenv("LOCK_SESSION") != "" {
|
||||||
Opts.LockSession = true
|
opts.LockSession = true
|
||||||
Opts.Sessions = false
|
opts.Sessions = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if Opts.Prefix != "" && !strings.Contains(Opts.Prefix, "/") {
|
if opts.Prefix != "" && !strings.Contains(opts.Prefix, "/") {
|
||||||
Opts.Prefix = Opts.Prefix + "/"
|
opts.Prefix = opts.Prefix + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
if Opts.AuthUser == "" && os.Getenv("AUTH_USER") != "" {
|
if opts.AuthUser == "" && os.Getenv("AUTH_USER") != "" {
|
||||||
Opts.AuthUser = os.Getenv("AUTH_USER")
|
opts.AuthUser = os.Getenv("AUTH_USER")
|
||||||
}
|
}
|
||||||
|
|
||||||
if Opts.AuthPass == "" && os.Getenv("AUTH_PASS") != "" {
|
if opts.AuthPass == "" && os.Getenv("AUTH_PASS") != "" {
|
||||||
Opts.AuthPass = os.Getenv("AUTH_PASS")
|
opts.AuthPass = os.Getenv("AUTH_PASS")
|
||||||
}
|
}
|
||||||
|
|
||||||
if Opts.Bookmark != "" && Opts.Sessions {
|
if opts.Bookmark != "" && opts.Sessions {
|
||||||
return errors.New("--bookmark is not allowed in multi-session mode")
|
return opts, errors.New("--bookmark is not allowed in multi-session mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
if Opts.ConnectBackend != "" {
|
if opts.ConnectBackend != "" {
|
||||||
if !Opts.Sessions {
|
if !opts.Sessions {
|
||||||
return errors.New("--sessions flag must be set")
|
return opts, errors.New("--sessions flag must be set")
|
||||||
}
|
}
|
||||||
if Opts.ConnectToken == "" {
|
if opts.ConnectToken == "" {
|
||||||
return errors.New("--connect-token flag must be set")
|
return opts, errors.New("--connect-token flag must be set")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Opts.ConnectToken != "" || Opts.ConnectHeaders != "" {
|
if opts.ConnectToken != "" || opts.ConnectHeaders != "" {
|
||||||
return errors.New("--connect-backend flag must be set")
|
return opts, errors.New("--connect-backend flag must be set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return opts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDefaultOptions() error {
|
||||||
|
opts, err := ParseOptions([]string{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
Opts = opts
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,50 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Options(t *testing.T) {
|
func TestParseOptions(t *testing.T) {
|
||||||
err := ParseOptions()
|
// Test default behavior
|
||||||
|
opts, err := ParseOptions([]string{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, false, opts.Sessions)
|
||||||
|
assert.Equal(t, "", opts.Prefix)
|
||||||
|
assert.Equal(t, "", opts.ConnectToken)
|
||||||
|
assert.Equal(t, "", opts.ConnectHeaders)
|
||||||
|
assert.Equal(t, false, opts.DisableSSH)
|
||||||
|
assert.Equal(t, false, opts.DisablePrettyJson)
|
||||||
|
assert.Equal(t, false, opts.DisableConnectionIdleTimeout)
|
||||||
|
assert.Equal(t, 180, opts.ConnectionIdleTimeout)
|
||||||
|
assert.Equal(t, false, opts.Cors)
|
||||||
|
assert.Equal(t, "*", opts.CorsOrigin)
|
||||||
|
|
||||||
|
// Test sessions
|
||||||
|
opts, err = ParseOptions([]string{"--sessions", "1"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, true, opts.Sessions)
|
||||||
|
|
||||||
|
opts, err = ParseOptions([]string{"--sessions", "1", "--bookmark", "test"})
|
||||||
|
assert.EqualError(t, err, "--bookmark is not allowed in multi-session mode")
|
||||||
|
|
||||||
|
// Test url prefix
|
||||||
|
opts, err = ParseOptions([]string{"--prefix", "pgweb"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "pgweb/", opts.Prefix)
|
||||||
|
|
||||||
|
opts, err = ParseOptions([]string{"--prefix", "pgweb/"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "pgweb/", opts.Prefix)
|
||||||
|
|
||||||
|
// Test connect backend options
|
||||||
|
opts, err = ParseOptions([]string{"--connect-backend", "test"})
|
||||||
|
assert.EqualError(t, err, "--sessions flag must be set")
|
||||||
|
|
||||||
|
opts, err = ParseOptions([]string{"--connect-backend", "test", "--sessions"})
|
||||||
|
assert.EqualError(t, err, "--connect-token flag must be set")
|
||||||
|
|
||||||
|
opts, err = ParseOptions([]string{"--connect-backend", "test", "--sessions", "--connect-token", "token"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, false, Opts.Sessions)
|
|
||||||
assert.Equal(t, "", Opts.Prefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_SessionsOption(t *testing.T) {
|
|
||||||
oldargs := os.Args
|
|
||||||
defer func() { os.Args = oldargs }()
|
|
||||||
|
|
||||||
os.Args = []string{"--sessions", "1"}
|
|
||||||
assert.NoError(t, ParseOptions())
|
|
||||||
assert.Equal(t, true, Opts.Sessions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_PrefixOption(t *testing.T) {
|
|
||||||
oldargs := os.Args
|
|
||||||
defer func() { os.Args = oldargs }()
|
|
||||||
|
|
||||||
os.Args = []string{"--prefix", "pgweb"}
|
|
||||||
assert.NoError(t, ParseOptions())
|
|
||||||
assert.Equal(t, "pgweb/", Opts.Prefix)
|
|
||||||
|
|
||||||
os.Args = []string{"--prefix", "pgweb/"}
|
|
||||||
assert.NoError(t, ParseOptions())
|
|
||||||
assert.Equal(t, "pgweb/", Opts.Prefix)
|
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func staticCssAppCss() (*asset, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "static/css/app.css", size: 11385, mode: os.FileMode(420), modTime: time.Unix(1509762282, 0)}
|
info := bindataFileInfo{name: "static/css/app.css", size: 11385, mode: os.FileMode(420), modTime: time.Unix(1517374041, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@ -301,7 +301,7 @@ func staticIndexHtml() (*asset, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "static/index.html", size: 12058, mode: os.FileMode(420), modTime: time.Unix(1513313307, 0)}
|
info := bindataFileInfo{name: "static/index.html", size: 12058, mode: os.FileMode(420), modTime: time.Unix(1517374041, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@ -361,7 +361,7 @@ func staticJsAppJs() (*asset, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "static/js/app.js", size: 34563, mode: os.FileMode(420), modTime: time.Unix(1512708944, 0)}
|
info := bindataFileInfo{name: "static/js/app.js", size: 34563, mode: os.FileMode(420), modTime: time.Unix(1517374041, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#
|
#
|
||||||
# Integartion testing with dockerized Postgres servers
|
# Integartion testing with dockerized Postgres servers
|
||||||
#
|
#
|
||||||
# Boot2Docker is deprecated and no longer supported.
|
|
||||||
# Requires Docker for Mac to run on OSX.
|
# Requires Docker for Mac to run on OSX.
|
||||||
# Install: https://docs.docker.com/engine/installation/mac/
|
# Install: https://docs.docker.com/engine/installation/mac/
|
||||||
#
|
#
|
||||||
@ -15,15 +14,20 @@ export PGPASSWORD=""
|
|||||||
export PGDATABASE="booktown"
|
export PGDATABASE="booktown"
|
||||||
export PGPORT="15432"
|
export PGPORT="15432"
|
||||||
|
|
||||||
for i in {1..6}
|
# TODO: Enable the 10.x branch when it's supported on Travis.
|
||||||
do
|
# Local 10.x version is required so that pg_dump can properly work with older versions.
|
||||||
export PGVERSION="9.$i"
|
# 10.x branch is normally supported.
|
||||||
|
versions="9.1 9.2 9.3 9.4 9.5 9.6"
|
||||||
|
|
||||||
echo "---------------- BEGIN TEST ----------------"
|
for i in $versions
|
||||||
|
do
|
||||||
|
export PGVERSION="$i"
|
||||||
|
|
||||||
|
echo "------------------------------- BEGIN TEST -------------------------------"
|
||||||
echo "Running tests against PostgreSQL v$PGVERSION"
|
echo "Running tests against PostgreSQL v$PGVERSION"
|
||||||
docker rm -f postgres || true
|
docker rm -f postgres || true
|
||||||
docker run -p $PGPORT:5432 --name postgres -e POSTGRES_PASSWORD=$PGPASSWORD -d postgres:$PGVERSION
|
docker run -p $PGPORT:5432 --name postgres -e POSTGRES_PASSWORD=$PGPASSWORD -d postgres:$PGVERSION
|
||||||
sleep 5
|
sleep 5
|
||||||
make test
|
make test
|
||||||
echo "---------------- END TEST ------------------"
|
echo "-------------------------------- END TEST --------------------------------"
|
||||||
done
|
done
|
Loading…
x
Reference in New Issue
Block a user