2014-10-21 05:32:47 +00:00
|
|
|
package main_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
2014-12-30 22:46:33 +00:00
|
|
|
"strings"
|
2014-10-21 05:32:47 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2015-01-06 03:14:43 +00:00
|
|
|
main "github.com/influxdb/influxdb/cmd/influxd"
|
2014-10-21 05:32:47 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Ensure that megabyte sizes can be parsed.
|
|
|
|
func TestSize_UnmarshalText_MB(t *testing.T) {
|
|
|
|
var s main.Size
|
|
|
|
if err := s.UnmarshalText([]byte("200m")); err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
} else if s != 200*(1<<20) {
|
|
|
|
t.Fatalf("unexpected size: %d", s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that gigabyte sizes can be parsed.
|
|
|
|
func TestSize_UnmarshalText_GB(t *testing.T) {
|
|
|
|
if typ := reflect.TypeOf(0); typ.Size() != 8 {
|
|
|
|
t.Skip("large gigabyte parsing on 64-bit arch only")
|
|
|
|
}
|
|
|
|
|
|
|
|
var s main.Size
|
|
|
|
if err := s.UnmarshalText([]byte("10g")); err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
} else if s != 10*(1<<30) {
|
|
|
|
t.Fatalf("unexpected size: %d", s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that a TOML configuration file can be parsed into a Config.
|
|
|
|
func TestParseConfig(t *testing.T) {
|
|
|
|
c, err := main.ParseConfig(testFile)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error: %s", err)
|
|
|
|
} else if c.Hostname != "myserver.com" {
|
|
|
|
t.Fatalf("hostname mismatch: %v", c.Hostname)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Logging.File != "influxdb.log" {
|
|
|
|
t.Fatalf("logging file mismatch: %v", c.Logging.File)
|
|
|
|
} else if c.Logging.Level != "info" {
|
|
|
|
t.Fatalf("logging level mismatch: %v", c.Logging.Level)
|
|
|
|
}
|
|
|
|
|
2015-01-02 21:41:02 +00:00
|
|
|
if !c.Authentication.Enabled {
|
|
|
|
t.Fatalf("authentication enabled mismatch: %v", c.Authentication.Enabled)
|
|
|
|
}
|
|
|
|
|
2014-10-21 05:32:47 +00:00
|
|
|
if c.Admin.Port != 8083 {
|
|
|
|
t.Fatalf("admin port mismatch: %v", c.Admin.Port)
|
|
|
|
} else if c.Admin.Assets != "./admin" {
|
|
|
|
t.Fatalf("admin assets mismatch: %v", c.Admin.Assets)
|
|
|
|
}
|
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
if c.Data.Port != main.DefaultBrokerPort {
|
|
|
|
t.Fatalf("data port mismatch: %v", c.Data.Port)
|
2014-10-21 05:32:47 +00:00
|
|
|
}
|
|
|
|
|
2015-01-08 20:28:10 +00:00
|
|
|
if len(c.Graphites) != 2 {
|
|
|
|
t.Fatalf("graphites mismatch. expected %v, got: %v", 2, len(c.Graphites))
|
2014-12-30 22:46:33 +00:00
|
|
|
}
|
|
|
|
|
2015-01-08 20:28:10 +00:00
|
|
|
tcpGraphite := c.Graphites[0]
|
2014-12-31 21:37:58 +00:00
|
|
|
switch {
|
|
|
|
case tcpGraphite.Enabled != true:
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite tcp enabled mismatch: expected: %v, got %v", true, tcpGraphite.Enabled)
|
2015-01-07 08:02:58 +00:00
|
|
|
case tcpGraphite.Addr != "192.168.0.1":
|
|
|
|
t.Fatalf("graphite tcp address mismatch: expected %v, got %v", "192.168.0.1", tcpGraphite.Addr)
|
2014-12-31 21:37:58 +00:00
|
|
|
case tcpGraphite.Port != 2003:
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite tcp port mismatch: expected %v, got %v", 2003, tcpGraphite.Port)
|
2014-12-31 21:37:58 +00:00
|
|
|
case tcpGraphite.Database != "graphite_tcp":
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite tcp database mismatch: expected %v, got %v", "graphite_tcp", tcpGraphite.Database)
|
2014-12-31 21:37:58 +00:00
|
|
|
case strings.ToLower(tcpGraphite.Protocol) != "tcp":
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite tcp protocol mismatch: expected %v, got %v", "tcp", strings.ToLower(tcpGraphite.Protocol))
|
2015-01-08 20:23:48 +00:00
|
|
|
case tcpGraphite.LastEnabled() != true:
|
2015-01-06 03:14:43 +00:00
|
|
|
t.Fatalf("graphite tcp name-position mismatch: expected %v, got %v", "last", tcpGraphite.NamePosition)
|
2015-01-08 00:15:39 +00:00
|
|
|
case tcpGraphite.NameSeparatorString() != "-":
|
|
|
|
t.Fatalf("graphite tcp name-separator mismatch: expected %v, got %v", "-", tcpGraphite.NameSeparatorString())
|
2014-12-30 22:46:33 +00:00
|
|
|
}
|
|
|
|
|
2015-01-08 20:28:10 +00:00
|
|
|
udpGraphite := c.Graphites[1]
|
2014-12-31 21:37:58 +00:00
|
|
|
switch {
|
|
|
|
case udpGraphite.Enabled != true:
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite udp enabled mismatch: expected: %v, got %v", true, udpGraphite.Enabled)
|
2015-01-07 08:02:58 +00:00
|
|
|
case udpGraphite.Addr != "192.168.0.2":
|
|
|
|
t.Fatalf("graphite udp address mismatch: expected %v, got %v", "192.168.0.2", udpGraphite.Addr)
|
2014-12-31 21:37:58 +00:00
|
|
|
case udpGraphite.Port != 2005:
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite udp port mismatch: expected %v, got %v", 2005, udpGraphite.Port)
|
2014-12-31 21:37:58 +00:00
|
|
|
case udpGraphite.Database != "graphite_udp":
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite database mismatch: expected %v, got %v", "graphite_udp", udpGraphite.Database)
|
2014-12-31 21:37:58 +00:00
|
|
|
case strings.ToLower(udpGraphite.Protocol) != "udp":
|
2014-12-30 22:46:33 +00:00
|
|
|
t.Fatalf("graphite udp protocol mismatch: expected %v, got %v", "udp", strings.ToLower(udpGraphite.Protocol))
|
2014-10-21 05:32:47 +00:00
|
|
|
}
|
|
|
|
|
2015-01-09 17:44:11 +00:00
|
|
|
switch {
|
|
|
|
case c.Collectd.Enabled != true:
|
|
|
|
t.Errorf("collectd enabled mismatch: expected: %v, got %v", true, c.Collectd.Enabled)
|
|
|
|
case c.Collectd.Addr != "192.168.0.3":
|
|
|
|
t.Errorf("collectd address mismatch: expected %v, got %v", "192.168.0.3", c.Collectd.Addr)
|
|
|
|
case c.Collectd.Port != 25827:
|
|
|
|
t.Errorf("collectd port mismatch: expected %v, got %v", 2005, c.Collectd.Port)
|
|
|
|
case c.Collectd.Database != "collectd_database":
|
|
|
|
t.Errorf("collectdabase mismatch: expected %v, got %v", "collectd_database", c.Collectd.Database)
|
|
|
|
case c.Collectd.TypesDB != "foo-db-type":
|
|
|
|
t.Errorf("collectd typesdb mismatch: expected %v, got %v", "foo-db-type", c.Collectd.TypesDB)
|
|
|
|
}
|
|
|
|
|
2014-12-30 22:46:50 +00:00
|
|
|
if c.Broker.Port != 8090 {
|
|
|
|
t.Fatalf("broker port mismatch: %v", c.Broker.Port)
|
|
|
|
} else if c.Broker.Dir != "/tmp/influxdb/development/broker" {
|
|
|
|
t.Fatalf("broker dir mismatch: %v", c.Broker.Dir)
|
|
|
|
} else if time.Duration(c.Broker.Timeout) != time.Second {
|
|
|
|
t.Fatalf("broker duration mismatch: %v", c.Broker.Timeout)
|
2014-10-21 05:32:47 +00:00
|
|
|
}
|
|
|
|
|
2014-12-30 22:46:50 +00:00
|
|
|
if c.Data.Dir != "/tmp/influxdb/development/db" {
|
|
|
|
t.Fatalf("data dir mismatch: %v", c.Data.Dir)
|
2014-10-21 05:32:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if c.Cluster.ProtobufPort != 8099 {
|
|
|
|
t.Fatalf("protobuf port mismatch: %v", c.Cluster.ProtobufPort)
|
|
|
|
} else if time.Duration(c.Cluster.ProtobufTimeout) != 2*time.Second {
|
|
|
|
t.Fatalf("protobuf timeout mismatch: %v", c.Cluster.ProtobufTimeout)
|
|
|
|
} else if time.Duration(c.Cluster.ProtobufHeartbeatInterval) != 200*time.Millisecond {
|
|
|
|
t.Fatalf("protobuf heartbeat interval mismatch: %v", c.Cluster.ProtobufHeartbeatInterval)
|
|
|
|
} else if time.Duration(c.Cluster.MinBackoff) != 100*time.Millisecond {
|
|
|
|
t.Fatalf("min backoff mismatch: %v", c.Cluster.MinBackoff)
|
|
|
|
} else if time.Duration(c.Cluster.MaxBackoff) != 1*time.Second {
|
|
|
|
t.Fatalf("max backoff mismatch: %v", c.Cluster.MaxBackoff)
|
|
|
|
} else if c.Cluster.MaxResponseBufferSize != 5 {
|
|
|
|
t.Fatalf("max response buffer size mismatch: %v", c.Cluster.MaxResponseBufferSize)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: UDP Servers testing.
|
|
|
|
/*
|
|
|
|
c.Assert(config.UdpServers, HasLen, 1)
|
|
|
|
c.Assert(config.UdpServers[0].Enabled, Equals, true)
|
|
|
|
c.Assert(config.UdpServers[0].Port, Equals, 4444)
|
|
|
|
c.Assert(config.UdpServers[0].Database, Equals, "test")
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
// Testing configuration file.
|
|
|
|
const testFile = `
|
2014-01-08 19:38:27 +00:00
|
|
|
# Welcome to the InfluxDB configuration file.
|
|
|
|
|
2014-03-24 15:33:28 +00:00
|
|
|
# If hostname (on the OS) doesn't return a name that can be resolved by the other
|
|
|
|
# systems in the cluster, you'll have to set the hostname to an IP or something
|
2014-06-25 02:59:47 +00:00
|
|
|
# that can be resolved here.
|
2014-10-21 05:32:47 +00:00
|
|
|
hostname = "myserver.com"
|
2014-01-08 19:38:27 +00:00
|
|
|
|
2015-01-02 21:41:02 +00:00
|
|
|
# Control authentication
|
|
|
|
[authentication]
|
|
|
|
enabled = true
|
|
|
|
|
2014-01-08 19:38:27 +00:00
|
|
|
[logging]
|
|
|
|
# logging level can be one of "debug", "info", "warn" or "error"
|
|
|
|
level = "info"
|
|
|
|
file = "influxdb.log"
|
|
|
|
|
|
|
|
# Configure the admin server
|
|
|
|
[admin]
|
2014-01-24 18:55:54 +00:00
|
|
|
port = 8083 # binding is disabled if the port isn't set
|
2014-01-08 19:38:27 +00:00
|
|
|
assets = "./admin"
|
|
|
|
|
|
|
|
# Configure the http api
|
|
|
|
[api]
|
2014-01-24 18:55:54 +00:00
|
|
|
ssl-port = 8087 # Ssl support is enabled if you set a port and cert
|
|
|
|
ssl-cert = "../cert.pem"
|
2014-01-08 19:38:27 +00:00
|
|
|
|
2014-06-25 02:59:47 +00:00
|
|
|
# connections will timeout after this amount of time. Ensures that clients that misbehave
|
2014-04-08 22:58:49 +00:00
|
|
|
# and keep alive connections they don't use won't end up connection a million times.
|
|
|
|
# However, if a request is taking longer than this to complete, could be a problem.
|
|
|
|
read-timeout = "5s"
|
|
|
|
|
2014-03-24 15:33:28 +00:00
|
|
|
[input_plugins]
|
|
|
|
|
2014-04-28 09:41:52 +00:00
|
|
|
[input_plugins.udp]
|
|
|
|
enabled = true
|
|
|
|
port = 4444
|
|
|
|
database = "test"
|
|
|
|
|
2015-01-08 20:28:10 +00:00
|
|
|
# Configure the Graphite servers
|
|
|
|
[[graphite]]
|
|
|
|
protocol = "TCP"
|
|
|
|
enabled = true
|
|
|
|
address = "192.168.0.1"
|
|
|
|
port = 2003
|
|
|
|
database = "graphite_tcp" # store graphite data in this database
|
|
|
|
name-position = "last"
|
|
|
|
name-separator = "-"
|
|
|
|
|
|
|
|
[[graphite]]
|
|
|
|
protocol = "udP"
|
|
|
|
enabled = true
|
|
|
|
address = "192.168.0.2"
|
|
|
|
port = 2005
|
|
|
|
database = "graphite_udp" # store graphite data in this database
|
2014-12-31 21:37:58 +00:00
|
|
|
|
2015-01-09 17:44:11 +00:00
|
|
|
# Configure collectd server
|
|
|
|
[collectd]
|
|
|
|
enabled = true
|
|
|
|
address = "192.168.0.3"
|
|
|
|
port = 25827
|
|
|
|
database = "collectd_database"
|
|
|
|
typesdb = "foo-db-type"
|
|
|
|
|
2014-01-08 19:38:27 +00:00
|
|
|
# Raft configuration
|
|
|
|
[raft]
|
|
|
|
# The raft port should be open between all servers in a cluster.
|
2014-12-30 22:46:50 +00:00
|
|
|
# Broker configuration
|
|
|
|
[broker]
|
|
|
|
# The broker port should be open between all servers in a cluster.
|
2014-01-08 19:38:27 +00:00
|
|
|
# However, this port shouldn't be accessible from the internet.
|
|
|
|
|
|
|
|
port = 8090
|
|
|
|
|
2014-12-30 22:46:50 +00:00
|
|
|
# Where the broker logs are stored. The user running InfluxDB will need read/write access.
|
|
|
|
dir = "/tmp/influxdb/development/broker"
|
2014-01-08 19:38:27 +00:00
|
|
|
|
2014-03-24 18:41:32 +00:00
|
|
|
# election-timeout = "2s"
|
|
|
|
|
2014-12-30 22:46:50 +00:00
|
|
|
[data]
|
2014-01-08 19:38:27 +00:00
|
|
|
dir = "/tmp/influxdb/development/db"
|
2014-12-30 22:46:50 +00:00
|
|
|
|
2014-02-21 00:50:01 +00:00
|
|
|
# How many requests to potentially buffer in memory. If the buffer gets filled then writes
|
|
|
|
# will still be logged and once the local storage has caught up (or compacted) the writes
|
|
|
|
# will be replayed from the WAL
|
2014-02-27 20:17:27 +00:00
|
|
|
write-buffer-size = 10000
|
2014-01-08 19:38:27 +00:00
|
|
|
|
2014-07-10 20:00:10 +00:00
|
|
|
# The server will check this often for shards that have expired and should be cleared.
|
|
|
|
retention-sweep-period = "10m"
|
|
|
|
|
2014-01-08 19:38:27 +00:00
|
|
|
[cluster]
|
|
|
|
# A comma separated list of servers to seed
|
|
|
|
# this server. this is only relevant when the
|
|
|
|
# server is joining a new cluster. Otherwise
|
|
|
|
# the server will use the list of known servers
|
|
|
|
# prior to shutting down. Any server can be pointed to
|
|
|
|
# as a seed. It will find the Raft leader automatically.
|
|
|
|
|
2014-12-30 22:46:50 +00:00
|
|
|
# Here's an example. Note that the port on the host is the same as the broker port.
|
2014-01-08 19:38:27 +00:00
|
|
|
seed-servers = ["hosta:8090", "hostb:8090"]
|
|
|
|
|
|
|
|
# Replication happens over a TCP connection with a Protobuf protocol.
|
|
|
|
# This port should be reachable between all servers in a cluster.
|
|
|
|
# However, this port shouldn't be accessible from the internet.
|
|
|
|
|
|
|
|
protobuf_port = 8099
|
2014-02-23 20:14:01 +00:00
|
|
|
protobuf_timeout = "2s" # the write timeout on the protobuf conn any duration parseable by time.ParseDuration
|
|
|
|
protobuf_heartbeat = "200ms" # the heartbeat interval between the servers. must be parseable by time.ParseDuration
|
2014-04-14 17:43:53 +00:00
|
|
|
protobuf_min_backoff = "100ms" # the minimum backoff after a failed heartbeat attempt
|
|
|
|
protobuf_max_backoff = "1s" # the maxmimum backoff after a failed heartbeat attempt
|
2014-02-05 20:02:04 +00:00
|
|
|
|
2014-02-21 00:50:01 +00:00
|
|
|
# How many write requests to potentially buffer in memory per server. If the buffer gets filled then writes
|
|
|
|
# will still be logged and once the server has caught up (or come back online) the writes
|
|
|
|
# will be replayed from the WAL
|
2014-02-27 20:17:27 +00:00
|
|
|
write-buffer-size = 10000
|
2014-02-21 00:50:01 +00:00
|
|
|
|
2014-04-08 17:28:58 +00:00
|
|
|
# the maximum number of responses to buffer from remote nodes, if the
|
|
|
|
# expected number of responses exceed this number then querying will
|
|
|
|
# happen sequentially and the buffer size will be limited to this
|
|
|
|
# number
|
|
|
|
max-response-buffer-size = 5
|
|
|
|
|
2014-03-26 20:59:42 +00:00
|
|
|
# When queries get distributed out to shards, they go in parallel. This means that results can get buffered
|
2014-06-25 02:59:47 +00:00
|
|
|
# in memory since results will come in any order, but have to be processed in the correct time order.
|
|
|
|
# Setting this higher will give better performance, but you'll need more memory. Setting this to 1 will ensure
|
2014-03-26 20:59:42 +00:00
|
|
|
# that you don't need to buffer in memory, but you won't get the best performance.
|
|
|
|
concurrent-shard-query-limit = 10
|
2014-02-25 18:18:05 +00:00
|
|
|
|
2014-02-05 20:02:04 +00:00
|
|
|
[leveldb]
|
|
|
|
|
|
|
|
# Maximum mmap open files, this will affect the virtual memory used by
|
|
|
|
# the process
|
2014-03-03 17:27:58 +00:00
|
|
|
# max-open-files = 40
|
2014-03-03 22:55:44 +00:00
|
|
|
lru-cache-size = "200m"
|
2014-10-21 05:32:47 +00:00
|
|
|
|
2014-03-03 22:51:09 +00:00
|
|
|
# The default setting on this is 0, which means unlimited. Set this to
|
|
|
|
# something if you want to limit the max number of open
|
|
|
|
# files. max-open-files is per shard so this * that will be max.
|
|
|
|
# max-open-shards = 0
|
2014-02-10 19:58:23 +00:00
|
|
|
|
2014-04-15 17:57:09 +00:00
|
|
|
# The default setting is 100. This option tells how many points will be fetched from LevelDb before
|
|
|
|
# they get flushed into backend.
|
|
|
|
point-batch-size = 50
|
2014-10-21 05:32:47 +00:00
|
|
|
`
|
2015-01-09 17:44:11 +00:00
|
|
|
|
2015-01-11 03:09:19 +00:00
|
|
|
func TestCollectd_ConnectionString(t *testing.T) {
|
2015-01-09 17:44:11 +00:00
|
|
|
var tests = []struct {
|
|
|
|
name string
|
|
|
|
defaultBindAddr string
|
|
|
|
connectionString string
|
|
|
|
config main.Collectd
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "No address or port provided from config",
|
|
|
|
defaultBindAddr: "192.168.0.1",
|
|
|
|
connectionString: "192.168.0.1:25826",
|
|
|
|
config: main.Collectd{},
|
|
|
|
},
|
|
|
|
{
|
2015-01-10 03:12:18 +00:00
|
|
|
name: "address provided, no port provided from config",
|
2015-01-09 17:44:11 +00:00
|
|
|
defaultBindAddr: "192.168.0.1",
|
|
|
|
connectionString: "192.168.0.2:25826",
|
|
|
|
config: main.Collectd{Addr: "192.168.0.2"},
|
|
|
|
},
|
|
|
|
{
|
2015-01-10 03:12:18 +00:00
|
|
|
name: "no address provided, port provided from config",
|
2015-01-09 17:44:11 +00:00
|
|
|
defaultBindAddr: "192.168.0.1",
|
|
|
|
connectionString: "192.168.0.1:25827",
|
|
|
|
config: main.Collectd{Port: 25827},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "both address and port provided from config",
|
|
|
|
defaultBindAddr: "192.168.0.1",
|
|
|
|
connectionString: "192.168.0.2:25827",
|
|
|
|
config: main.Collectd{Addr: "192.168.0.2", Port: 25827},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Logf("test: %q", test.name)
|
|
|
|
s := test.config.ConnectionString(test.defaultBindAddr)
|
|
|
|
if s != test.connectionString {
|
2015-01-10 03:12:18 +00:00
|
|
|
t.Errorf("connection string mismatch, expected: %q, got: %q", test.connectionString, s)
|
2015-01-09 17:44:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|