VMware vSphere Integrated Containers provider (#206)
* Add Virtual Kubelet provider for VIC Initial virtual kubelet provider for VMware VIC. This provider currently handles creating and starting of a pod VM via the VIC portlayer and persona server. Image store handling via the VIC persona server. This provider currently requires the feature/wolfpack branch of VIC. * Added pod stop and delete. Also added node capacity. Added the ability to stop and delete pod VMs via VIC. Also retrieve node capacity information from the VCH. * Cleanup and readme file Some file clean up and added a Readme.md markdown file for the VIC provider. * Cleaned up errors, added function comments, moved operation code 1. Cleaned up error handling. Set standard for creating errors. 2. Added method prototype comments for all interface functions. 3. Moved PodCreator, PodStarter, PodStopper, and PodDeleter to a new folder. * Add mocking code and unit tests for podcache, podcreator, and podstarter Used the unit test framework used in VIC to handle assertions in the provider's unit test. Mocking code generated using OSS project mockery, which is compatible with the testify assertion framework. * Vendored packages for the VIC provider Requires feature/wolfpack branch of VIC and a few specific commit sha of projects used within VIC. * Implementation of POD Stopper and Deleter unit tests (#4) * Updated files for initial PR
This commit is contained in:
101
vendor/github.com/vmware/vic/pkg/log/log.go
generated
vendored
Normal file
101
vendor/github.com/vmware/vic/pkg/log/log.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/vmware/vic/pkg/log/syslog"
|
||||
)
|
||||
|
||||
type LoggingConfig struct {
|
||||
Formatter logrus.Formatter
|
||||
Level logrus.Level
|
||||
Syslog *SyslogConfig
|
||||
}
|
||||
|
||||
type SyslogConfig struct {
|
||||
Network string
|
||||
RAddr string
|
||||
Tag string
|
||||
Priority syslog.Priority
|
||||
}
|
||||
|
||||
var initializer struct {
|
||||
once sync.Once
|
||||
err error
|
||||
}
|
||||
|
||||
func NewLoggingConfig() *LoggingConfig {
|
||||
return &LoggingConfig{
|
||||
Formatter: NewTextFormatter(),
|
||||
Level: logrus.InfoLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func Init(cfg *LoggingConfig) error {
|
||||
initializer.once.Do(
|
||||
func() {
|
||||
|
||||
var err error
|
||||
|
||||
logger := logrus.StandardLogger()
|
||||
f := logger.Formatter
|
||||
l := logger.Level
|
||||
defer func() {
|
||||
initializer.err = err
|
||||
if err != nil {
|
||||
// revert
|
||||
logrus.SetFormatter(f)
|
||||
logrus.SetLevel(l)
|
||||
}
|
||||
}()
|
||||
|
||||
logrus.SetFormatter(cfg.Formatter)
|
||||
logrus.SetLevel(cfg.Level)
|
||||
|
||||
logrus.Debugf("log cfg: %+v", *cfg)
|
||||
|
||||
hook, err := CreateSyslogHook(cfg)
|
||||
if err == nil && hook != nil {
|
||||
logrus.AddHook(hook)
|
||||
}
|
||||
})
|
||||
|
||||
return initializer.err
|
||||
}
|
||||
|
||||
func CreateSyslogHook(cfg *LoggingConfig) (logrus.Hook, error) {
|
||||
if cfg.Syslog == nil {
|
||||
return nil, nil
|
||||
}
|
||||
hook, err := syslog.NewHook(
|
||||
cfg.Syslog.Network,
|
||||
cfg.Syslog.RAddr,
|
||||
cfg.Syslog.Priority,
|
||||
cfg.Syslog.Tag,
|
||||
)
|
||||
if err != nil {
|
||||
// not a fatal error, so just log a warning
|
||||
logrus.Warnf("error trying to initialize syslog: %s", err)
|
||||
}
|
||||
return hook, err
|
||||
}
|
||||
|
||||
func (l *LoggingConfig) SetLogLevel(level uint8) {
|
||||
l.Level = logrus.Level(level)
|
||||
}
|
||||
23
vendor/github.com/vmware/vic/pkg/log/syslog/dialer.go
generated
vendored
Normal file
23
vendor/github.com/vmware/vic/pkg/log/syslog/dialer.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import "time"
|
||||
|
||||
const defaultDialTimeout = 1 * time.Minute
|
||||
|
||||
type dialer interface {
|
||||
dial() (Writer, error)
|
||||
}
|
||||
64
vendor/github.com/vmware/vic/pkg/log/syslog/formatter.go
generated
vendored
Normal file
64
vendor/github.com/vmware/vic/pkg/log/syslog/formatter.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type formatter interface {
|
||||
Format(p Priority, ts time.Time, hostname, tag, msg string) string
|
||||
}
|
||||
|
||||
type localFormatter struct{}
|
||||
|
||||
func (l *localFormatter) Format(p Priority, ts time.Time, _, tag, msg string) string {
|
||||
return fmt.Sprintf("<%d>%s %s[%d]: %s", p, ts.Format(time.Stamp), tag, os.Getpid(), msg)
|
||||
}
|
||||
|
||||
type rfc3164Formatter struct{}
|
||||
|
||||
func (c *rfc3164Formatter) Format(p Priority, ts time.Time, hostname, tag, msg string) string {
|
||||
return fmt.Sprintf("<%d>%s %s %s[%d]: %s", p, ts.Format(time.RFC3339), hostname, tag, os.Getpid(), msg)
|
||||
}
|
||||
|
||||
type netDialer interface {
|
||||
dial() (net.Conn, error)
|
||||
}
|
||||
|
||||
type defaultNetDialer struct {
|
||||
network, address string
|
||||
}
|
||||
|
||||
func (d *defaultNetDialer) dial() (net.Conn, error) {
|
||||
Logger.Infof("trying to connect to %s://%s", d.network, d.address)
|
||||
return net.DialTimeout(d.network, d.address, defaultDialTimeout)
|
||||
}
|
||||
|
||||
func newFormatter(network string, f Format) formatter {
|
||||
if network == "" {
|
||||
return &localFormatter{}
|
||||
}
|
||||
|
||||
switch f {
|
||||
case RFC3164:
|
||||
return &rfc3164Formatter{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
56
vendor/github.com/vmware/vic/pkg/log/syslog/formatter_test.go
generated
vendored
Normal file
56
vendor/github.com/vmware/vic/pkg/log/syslog/formatter_test.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewFormatter(t *testing.T) {
|
||||
f := newFormatter("", RFC3164)
|
||||
assert.IsType(t, &localFormatter{}, f)
|
||||
|
||||
f = newFormatter("tcp", RFC3164)
|
||||
assert.IsType(t, &rfc3164Formatter{}, f)
|
||||
|
||||
f = newFormatter("tcp", 123)
|
||||
assert.Nil(t, f)
|
||||
}
|
||||
|
||||
func TestFormatterFormats(t *testing.T) {
|
||||
var tests = []struct {
|
||||
format string
|
||||
tsLayout string
|
||||
local bool
|
||||
f formatter
|
||||
}{
|
||||
{"<%d>%s %s[%d]: %s", time.Stamp, true, &localFormatter{}},
|
||||
{"<%d>%s %s %s[%d]: %s", time.RFC3339, false, &rfc3164Formatter{}},
|
||||
}
|
||||
|
||||
for _, te := range tests {
|
||||
ts := time.Now()
|
||||
if te.local {
|
||||
assert.Equal(t, fmt.Sprintf(te.format, priority, ts.Format(te.tsLayout), tag, os.Getpid(), "foo"), te.f.Format(priority, ts, "host", tag, "foo"))
|
||||
} else {
|
||||
assert.Equal(t, fmt.Sprintf(te.format, priority, ts.Format(te.tsLayout), "host", tag, os.Getpid(), "foo"), te.f.Format(priority, ts, "host", tag, "foo"))
|
||||
}
|
||||
}
|
||||
}
|
||||
71
vendor/github.com/vmware/vic/pkg/log/syslog/hook.go
generated
vendored
Normal file
71
vendor/github.com/vmware/vic/pkg/log/syslog/hook.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
type Hook struct {
|
||||
writer Writer
|
||||
}
|
||||
|
||||
func NewHook(network, raddr string, priority Priority, tag string) (*Hook, error) {
|
||||
return newHook(&defaultDialer{
|
||||
network: network,
|
||||
raddr: raddr,
|
||||
priority: priority,
|
||||
tag: tag,
|
||||
})
|
||||
}
|
||||
|
||||
func newHook(d dialer) (*Hook, error) {
|
||||
hook := &Hook{}
|
||||
|
||||
var err error
|
||||
hook.writer, err = d.dial()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hook, nil
|
||||
}
|
||||
|
||||
func (hook *Hook) Fire(entry *logrus.Entry) error {
|
||||
return hook.writeEntry(entry)
|
||||
}
|
||||
|
||||
func (hook *Hook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
||||
|
||||
func (hook *Hook) writeEntry(entry *logrus.Entry) error {
|
||||
// just use the message since the timestamp
|
||||
// is added by the syslog package
|
||||
line := entry.Message
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel, logrus.FatalLevel:
|
||||
return hook.writer.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.writer.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
return hook.writer.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
return hook.writer.Info(line)
|
||||
case logrus.DebugLevel:
|
||||
return hook.writer.Debug(line)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
126
vendor/github.com/vmware/vic/pkg/log/syslog/hook_test.go
generated
vendored
Normal file
126
vendor/github.com/vmware/vic/pkg/log/syslog/hook_test.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestNewSyslogHook(t *testing.T) {
|
||||
// error case
|
||||
d := &mockDialer{}
|
||||
d.On("dial").Return(nil, assert.AnError)
|
||||
h, err := newHook(d)
|
||||
assert.Nil(t, h)
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, assert.AnError.Error())
|
||||
d.AssertCalled(t, "dial")
|
||||
d.AssertNumberOfCalls(t, "dial", 1)
|
||||
|
||||
// no error
|
||||
d = &mockDialer{}
|
||||
w := &MockWriter{}
|
||||
d.On("dial").Return(w, nil)
|
||||
h, err = newHook(d)
|
||||
assert.NotNil(t, h)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, w, h.writer)
|
||||
d.AssertCalled(t, "dial")
|
||||
d.AssertNumberOfCalls(t, "dial", 1)
|
||||
}
|
||||
|
||||
func TestLevels(t *testing.T) {
|
||||
m := &MockWriter{}
|
||||
d := &mockDialer{}
|
||||
d.On("dial").Return(m, nil)
|
||||
h, err := newHook(d)
|
||||
|
||||
assert.NotNil(t, h)
|
||||
assert.NoError(t, err)
|
||||
|
||||
m.On("Crit", mock.Anything).Return(nil)
|
||||
m.On("Err", mock.Anything).Return(nil)
|
||||
m.On("Warning", mock.Anything).Return(nil)
|
||||
m.On("Debug", mock.Anything).Return(nil)
|
||||
m.On("Info", mock.Anything).Return(nil)
|
||||
|
||||
var tests = []struct {
|
||||
entry *logrus.Entry
|
||||
f string
|
||||
}{
|
||||
{
|
||||
entry: &logrus.Entry{Message: "panic", Level: logrus.PanicLevel},
|
||||
f: "Crit",
|
||||
},
|
||||
{
|
||||
entry: &logrus.Entry{Message: "fatal", Level: logrus.FatalLevel},
|
||||
f: "Crit",
|
||||
},
|
||||
{
|
||||
entry: &logrus.Entry{Message: "error", Level: logrus.ErrorLevel},
|
||||
f: "Err",
|
||||
},
|
||||
{
|
||||
entry: &logrus.Entry{Message: "warn", Level: logrus.WarnLevel},
|
||||
f: "Warning",
|
||||
},
|
||||
{
|
||||
entry: &logrus.Entry{Message: "info", Level: logrus.InfoLevel},
|
||||
f: "Info",
|
||||
},
|
||||
{
|
||||
entry: &logrus.Entry{Message: "debug", Level: logrus.DebugLevel},
|
||||
f: "Debug",
|
||||
},
|
||||
}
|
||||
|
||||
calls := make(map[string]int)
|
||||
for _, te := range tests {
|
||||
calls[te.f] = 0
|
||||
}
|
||||
|
||||
for _, te := range tests {
|
||||
assert.NoError(t, h.writeEntry(te.entry))
|
||||
calls[te.f]++
|
||||
m.AssertCalled(t, te.f, te.entry.Message)
|
||||
m.AssertNumberOfCalls(t, te.f, calls[te.f])
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnect(t *testing.T) {
|
||||
// attempt a connection to a server that
|
||||
// does not exist
|
||||
h, err := NewHook(
|
||||
"tcp",
|
||||
"foo:514",
|
||||
Info,
|
||||
"test",
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
h.Fire(&logrus.Entry{
|
||||
Message: "foo",
|
||||
Level: logrus.InfoLevel,
|
||||
})
|
||||
|
||||
<-time.After(5 * time.Second)
|
||||
}
|
||||
55
vendor/github.com/vmware/vic/pkg/log/syslog/mock_addr_test.go
generated
vendored
Normal file
55
vendor/github.com/vmware/vic/pkg/log/syslog/mock_addr_test.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockAddr is an autogenerated mock type for the Addr type
|
||||
type MockAddr struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Network provides a mock function with given fields:
|
||||
func (_m *MockAddr) Network() string {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// String provides a mock function with given fields:
|
||||
func (_m *MockAddr) String() string {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
var _ net.Addr = (*MockAddr)(nil)
|
||||
46
vendor/github.com/vmware/vic/pkg/log/syslog/mock_dialer_test.go
generated
vendored
Normal file
46
vendor/github.com/vmware/vic/pkg/log/syslog/mock_dialer_test.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package syslog
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// mockDialer is an autogenerated mock type for the dialer type
|
||||
type mockDialer struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// dial provides a mock function with given fields:
|
||||
func (_m *mockDialer) dial() (Writer, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 Writer
|
||||
if rf, ok := ret.Get(0).(func() Writer); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(Writer)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
var _ dialer = (*mockDialer)(nil)
|
||||
38
vendor/github.com/vmware/vic/pkg/log/syslog/mock_formatter_test.go
generated
vendored
Normal file
38
vendor/github.com/vmware/vic/pkg/log/syslog/mock_formatter_test.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package syslog
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import time "time"
|
||||
|
||||
// mockFormatter is an autogenerated mock type for the formatter type
|
||||
type mockFormatter struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Format provides a mock function with given fields: p, ts, hostname, tag, msg
|
||||
func (_m *mockFormatter) Format(p Priority, ts time.Time, hostname string, tag string, msg string) string {
|
||||
ret := _m.Called(p, ts, hostname, tag, msg)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(Priority, time.Time, string, string, string) string); ok {
|
||||
r0 = rf(p, ts, hostname, tag, msg)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
var _ formatter = (*mockFormatter)(nil)
|
||||
155
vendor/github.com/vmware/vic/pkg/log/syslog/mock_netconn_test.go
generated
vendored
Normal file
155
vendor/github.com/vmware/vic/pkg/log/syslog/mock_netconn_test.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package syslog
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import net "net"
|
||||
import time "time"
|
||||
|
||||
// MockConn is an autogenerated mock type for the Conn type
|
||||
type MockNetConn struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *MockNetConn) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// LocalAddr provides a mock function with given fields:
|
||||
func (_m *MockNetConn) LocalAddr() net.Addr {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 net.Addr
|
||||
if rf, ok := ret.Get(0).(func() net.Addr); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(net.Addr)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Read provides a mock function with given fields: b
|
||||
func (_m *MockNetConn) Read(b []byte) (int, error) {
|
||||
ret := _m.Called(b)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func([]byte) int); ok {
|
||||
r0 = rf(b)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func([]byte) error); ok {
|
||||
r1 = rf(b)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// RemoteAddr provides a mock function with given fields:
|
||||
func (_m *MockNetConn) RemoteAddr() net.Addr {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 net.Addr
|
||||
if rf, ok := ret.Get(0).(func() net.Addr); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(net.Addr)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetDeadline provides a mock function with given fields: t
|
||||
func (_m *MockNetConn) SetDeadline(t time.Time) error {
|
||||
ret := _m.Called(t)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(time.Time) error); ok {
|
||||
r0 = rf(t)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetReadDeadline provides a mock function with given fields: t
|
||||
func (_m *MockNetConn) SetReadDeadline(t time.Time) error {
|
||||
ret := _m.Called(t)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(time.Time) error); ok {
|
||||
r0 = rf(t)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetWriteDeadline provides a mock function with given fields: t
|
||||
func (_m *MockNetConn) SetWriteDeadline(t time.Time) error {
|
||||
ret := _m.Called(t)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(time.Time) error); ok {
|
||||
r0 = rf(t)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Write provides a mock function with given fields: b
|
||||
func (_m *MockNetConn) Write(b []byte) (int, error) {
|
||||
ret := _m.Called(b)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func([]byte) int); ok {
|
||||
r0 = rf(b)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func([]byte) error); ok {
|
||||
r1 = rf(b)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
var _ net.Conn = (*MockNetConn)(nil)
|
||||
47
vendor/github.com/vmware/vic/pkg/log/syslog/mock_netdialer_test.go
generated
vendored
Normal file
47
vendor/github.com/vmware/vic/pkg/log/syslog/mock_netdialer_test.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package syslog
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import net "net"
|
||||
|
||||
// mockNetDialer is an autogenerated mock type for the netDialer type
|
||||
type mockNetDialer struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// dial provides a mock function with given fields:
|
||||
func (_m *mockNetDialer) dial() (net.Conn, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 net.Conn
|
||||
if rf, ok := ret.Get(0).(func() net.Conn); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(net.Conn)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
var _ netDialer = (*mockNetDialer)(nil)
|
||||
174
vendor/github.com/vmware/vic/pkg/log/syslog/mock_writer_test.go
generated
vendored
Normal file
174
vendor/github.com/vmware/vic/pkg/log/syslog/mock_writer_test.go
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package syslog
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// MockWriter is an autogenerated mock type for the Writer type
|
||||
type MockWriter struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *MockWriter) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Crit provides a mock function with given fields: _a0
|
||||
func (_m *MockWriter) Crit(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Debug provides a mock function with given fields: _a0
|
||||
func (_m *MockWriter) Debug(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Emerg provides a mock function with given fields: _a0
|
||||
func (_m *MockWriter) Emerg(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Err provides a mock function with given fields: _a0
|
||||
func (_m *MockWriter) Err(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Info provides a mock function with given fields: _a0
|
||||
func (_m *MockWriter) Info(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Warning provides a mock function with given fields: _a0
|
||||
func (_m *MockWriter) Warning(_a0 string) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// WithPriority provides a mock function with given fields: priority
|
||||
func (_m *MockWriter) WithPriority(priority Priority) Writer {
|
||||
ret := _m.Called(priority)
|
||||
|
||||
var r0 Writer
|
||||
if rf, ok := ret.Get(0).(func(Priority) Writer); ok {
|
||||
r0 = rf(priority)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(Writer)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// WithTag provides a mock function with given fields: tag
|
||||
func (_m *MockWriter) WithTag(tag string) Writer {
|
||||
ret := _m.Called(tag)
|
||||
|
||||
var r0 Writer
|
||||
if rf, ok := ret.Get(0).(func(string) Writer); ok {
|
||||
r0 = rf(tag)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(Writer)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Write provides a mock function with given fields: p
|
||||
func (_m *MockWriter) Write(p []byte) (int, error) {
|
||||
ret := _m.Called(p)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func([]byte) int); ok {
|
||||
r0 = rf(p)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func([]byte) error); ok {
|
||||
r1 = rf(p)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
var _ Writer = (*MockWriter)(nil)
|
||||
156
vendor/github.com/vmware/vic/pkg/log/syslog/syslog.go
generated
vendored
Normal file
156
vendor/github.com/vmware/vic/pkg/log/syslog/syslog.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Priority is a combination of the syslog facility and
|
||||
// severity. For example, Alert | Ftp sends an alert severity
|
||||
// message from the FTP facility. The default severity is Emerg;
|
||||
// the default facility is Kern.
|
||||
type Priority int
|
||||
|
||||
const severityMask = 0x07
|
||||
const facilityMask = 0xf8
|
||||
|
||||
// maxLogBuffer was set to 100 but debug logging of config overflows that easily so pushing it up
|
||||
const maxLogBuffer = 500
|
||||
|
||||
const (
|
||||
// Severity.
|
||||
|
||||
// From /usr/include/sys/syslog.h.
|
||||
// These are the same on Linux, BSD, and OS X.
|
||||
Emerg Priority = iota // LOG_EMERG
|
||||
Alert // LOG_ALERT
|
||||
Crit // LOG_CRIT
|
||||
Err // LOG_ERR
|
||||
Warning // LOG_WARNING
|
||||
Notice // LOG_NOTICE
|
||||
Info // LOG_INFO
|
||||
Debug // LOG_DEBUG
|
||||
)
|
||||
|
||||
const (
|
||||
// Facility.
|
||||
|
||||
// From /usr/include/sys/syslog.h.
|
||||
// These are the same up to LOG_FTP on Linux, BSD, and OS X.
|
||||
Kern Priority = iota << 3 // LOG_KERN
|
||||
User // LOG_USER
|
||||
Mail // LOG_MAIL
|
||||
Daemon // LOG_DAEMON
|
||||
Auth // LOG_AUTH
|
||||
Syslog // LOG_SYSLOG
|
||||
Lpr // LOG_LPR
|
||||
News // LOG_NEWS
|
||||
Uucp // LOG_UUCP
|
||||
Cron // LOG_CRON
|
||||
Authpriv // LOG_AUTHPRIV
|
||||
Ftp // LOG_FTP
|
||||
_ // unused
|
||||
_ // unused
|
||||
_ // unused
|
||||
_ // unused
|
||||
Local0 // LOG_LOCAL0
|
||||
Local1 // LOG_LOCAL1
|
||||
Local2 // LOG_LOCAL2
|
||||
Local3 // LOG_LOCAL3
|
||||
Local4 // LOG_LOCAL4
|
||||
Local5 // LOG_LOCAL5
|
||||
Local6 // LOG_LOCAL6
|
||||
Local7 // LOG_LOCAL7
|
||||
)
|
||||
|
||||
// New establishes a new connection to the system log daemon. Each
|
||||
// write to the returned writer sends a log message with the given
|
||||
// priority and prefix.
|
||||
func New(priority Priority, tag string) (Writer, error) {
|
||||
return Dial("", "", priority, tag)
|
||||
}
|
||||
|
||||
// Dial establishes a connection to a log daemon by connecting to
|
||||
// address raddr on the specified network. Each write to the returned
|
||||
// writer sends a log message with the given facility, severity and
|
||||
// tag.
|
||||
// If network is empty, Dial will connect to the local syslog server.
|
||||
func Dial(network, raddr string, priority Priority, tag string) (Writer, error) {
|
||||
d := &defaultDialer{
|
||||
network: network,
|
||||
raddr: raddr,
|
||||
tag: tag,
|
||||
priority: priority,
|
||||
}
|
||||
|
||||
return d.dial()
|
||||
}
|
||||
|
||||
type defaultDialer struct {
|
||||
network, raddr, tag string
|
||||
priority Priority
|
||||
}
|
||||
|
||||
func validPriority(priority Priority) bool {
|
||||
return priority >= 0 && priority <= Local7|Debug
|
||||
}
|
||||
|
||||
func (d *defaultDialer) dial() (Writer, error) {
|
||||
if !validPriority(d.priority) {
|
||||
return nil, errors.New("log/syslog: invalid priority")
|
||||
}
|
||||
|
||||
tag := MakeTag("", d.tag)
|
||||
// #nosec: Errors unhandled.
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
w := newWriter(d.priority, tag, hostname, newNetDialer(d.network, d.raddr), newFormatter(d.network, RFC3164))
|
||||
|
||||
go w.run()
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
const sep = "/"
|
||||
|
||||
// MakeTag returns prfeix + sep + proc if prefix is not empty.
|
||||
// If proc is empty, proc is set to filepath.Base(os.Args[0]).
|
||||
// If prefix is empty, MakeTag returns proc.
|
||||
func MakeTag(prefix, proc string) string {
|
||||
if len(proc) == 0 {
|
||||
proc = filepath.Base(os.Args[0])
|
||||
}
|
||||
|
||||
if len(prefix) > 0 {
|
||||
return prefix + sep + proc
|
||||
}
|
||||
|
||||
return proc
|
||||
}
|
||||
|
||||
// Logger is the logger object used by the package
|
||||
var Logger = logrus.New()
|
||||
|
||||
// Format is the syslog format, e.g. RFC 3164
|
||||
type Format int
|
||||
|
||||
const (
|
||||
RFC3164 Format = iota
|
||||
)
|
||||
80
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_test.go
generated
vendored
Normal file
80
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_test.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
network = "tcp"
|
||||
raddr = "localhost:514"
|
||||
tag = "test"
|
||||
priority = Info | Daemon
|
||||
)
|
||||
|
||||
func TestMakeTag(t *testing.T) {
|
||||
p := filepath.Base(os.Args[0])
|
||||
var tests = []struct {
|
||||
prefix string
|
||||
proc string
|
||||
out string
|
||||
}{
|
||||
{
|
||||
prefix: "",
|
||||
proc: "",
|
||||
out: p,
|
||||
},
|
||||
{
|
||||
prefix: "",
|
||||
proc: "foo",
|
||||
out: "foo",
|
||||
},
|
||||
{
|
||||
prefix: "foo",
|
||||
proc: "",
|
||||
out: "foo" + sep + p,
|
||||
},
|
||||
{
|
||||
prefix: "bar",
|
||||
proc: "foo",
|
||||
out: "bar" + sep + "foo",
|
||||
},
|
||||
}
|
||||
|
||||
for _, te := range tests {
|
||||
out := MakeTag(te.prefix, te.proc)
|
||||
assert.Equal(t, te.out, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultDialerBadPriority(t *testing.T) {
|
||||
d := &defaultDialer{
|
||||
priority: -1,
|
||||
}
|
||||
|
||||
w, err := d.dial()
|
||||
assert.Nil(t, w)
|
||||
assert.Error(t, err)
|
||||
|
||||
d.priority = (Local7 | Debug) + 1
|
||||
w, err = d.dial()
|
||||
assert.Nil(t, w)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
53
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_unix.go
generated
vendored
Normal file
53
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_unix.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
type unixSyslogDialer struct{}
|
||||
|
||||
// unixSyslog opens a connection to the syslog daemon running on the
|
||||
// local machine using a Unix domain socket.
|
||||
func (u *unixSyslogDialer) dial() (net.Conn, error) {
|
||||
logTypes := []string{"unixgram", "unix"}
|
||||
logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"}
|
||||
for _, network := range logTypes {
|
||||
for _, path := range logPaths {
|
||||
conn, err := net.Dial(network, path)
|
||||
if err != nil {
|
||||
continue
|
||||
} else {
|
||||
return conn, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New("Unix syslog delivery error")
|
||||
}
|
||||
|
||||
func newNetDialer(network, address string) netDialer {
|
||||
if network == "" {
|
||||
return &unixSyslogDialer{}
|
||||
}
|
||||
|
||||
return &defaultNetDialer{
|
||||
network: network,
|
||||
address: address,
|
||||
}
|
||||
}
|
||||
26
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_unix_test.go
generated
vendored
Normal file
26
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_unix_test.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package syslog
|
||||
|
||||
import "testing"
|
||||
import "github.com/stretchr/testify/assert"
|
||||
|
||||
func TestNewNetDialer(t *testing.T) {
|
||||
d := newNetDialer("", "")
|
||||
|
||||
assert.IsType(t, &unixSyslogDialer{}, d)
|
||||
}
|
||||
22
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_windows.go
generated
vendored
Normal file
22
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_windows.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
func newNetDialer(network, address string) netDialer {
|
||||
return &defaultNetDialer{
|
||||
network: network,
|
||||
address: address,
|
||||
}
|
||||
}
|
||||
25
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_windows_test.go
generated
vendored
Normal file
25
vendor/github.com/vmware/vic/pkg/log/syslog/syslog_windows_test.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build windows
|
||||
|
||||
package syslog
|
||||
|
||||
import "testing"
|
||||
import "github.com/stretchr/testify/assert"
|
||||
|
||||
func TestNewNetDialer(t *testing.T) {
|
||||
d := newNetDialer("tcp", "foo")
|
||||
assert.IsType(t, &defaultDialer{}, d)
|
||||
}
|
||||
270
vendor/github.com/vmware/vic/pkg/log/syslog/writer.go
generated
vendored
Normal file
270
vendor/github.com/vmware/vic/pkg/log/syslog/writer.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Writer interface {
|
||||
io.WriteCloser
|
||||
|
||||
Emerg(string) error
|
||||
Crit(string) error
|
||||
Err(string) error
|
||||
Warning(string) error
|
||||
Info(string) error
|
||||
Debug(string) error
|
||||
|
||||
WithTag(tag string) Writer
|
||||
WithPriority(priority Priority) Writer
|
||||
}
|
||||
|
||||
type writer struct {
|
||||
priority Priority
|
||||
tag string
|
||||
hostname string
|
||||
|
||||
msgs chan *msg
|
||||
once sync.Once
|
||||
done, running chan struct{}
|
||||
|
||||
dialer netDialer
|
||||
conn net.Conn
|
||||
formatter formatter
|
||||
|
||||
parent *writer
|
||||
}
|
||||
|
||||
type msg struct {
|
||||
p Priority
|
||||
tag string
|
||||
msg string
|
||||
}
|
||||
|
||||
func newWriter(priority Priority, tag, hostname string, dialer netDialer, f formatter) *writer {
|
||||
return &writer{
|
||||
priority: priority,
|
||||
tag: tag,
|
||||
hostname: hostname,
|
||||
dialer: dialer,
|
||||
msgs: make(chan *msg, maxLogBuffer),
|
||||
done: make(chan struct{}),
|
||||
running: make(chan struct{}),
|
||||
formatter: f,
|
||||
}
|
||||
}
|
||||
|
||||
// connect makes a connection to the syslog server.
|
||||
// It must be called with w.mu held.
|
||||
func (w *writer) connect() (err error) {
|
||||
if w.conn != nil {
|
||||
// ignore err from close, it makes sense to continue anyway
|
||||
w.conn.Close()
|
||||
w.conn = nil
|
||||
}
|
||||
|
||||
Logger.Infof("trying to connect to syslog server")
|
||||
w.conn, err = w.dialer.dial()
|
||||
if err == nil {
|
||||
Logger.Info("successfully connected to syslog server")
|
||||
if w.hostname == "" {
|
||||
// #nosec: Errors unhandled.
|
||||
w.hostname, _, _ = net.SplitHostPort(w.conn.LocalAddr().String())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Write sends a log message to the syslog daemon.
|
||||
func (w *writer) Write(b []byte) (int, error) {
|
||||
w.queueWrite(w.priority, w.tag, string(b))
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// Close closes a connection to the syslog daemon.
|
||||
func (w *writer) Close() error {
|
||||
for w.parent != nil {
|
||||
w = w.parent
|
||||
}
|
||||
|
||||
w.once.Do(func() {
|
||||
close(w.msgs)
|
||||
select {
|
||||
case <-w.running:
|
||||
<-w.done
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Emerg logs a message with severity Emerg, ignoring the severity
|
||||
// passed to New.
|
||||
func (w *writer) Emerg(m string) error {
|
||||
return w.queueWrite(Emerg, w.tag, m)
|
||||
}
|
||||
|
||||
// Alert logs a message with severity Alert, ignoring the severity
|
||||
// passed to New.
|
||||
func (w *writer) Alert(m string) error {
|
||||
return w.queueWrite(Alert, w.tag, m)
|
||||
}
|
||||
|
||||
// Crit logs a message with severity Crit, ignoring the severity
|
||||
// passed to New.
|
||||
func (w *writer) Crit(m string) error {
|
||||
return w.queueWrite(Crit, w.tag, m)
|
||||
}
|
||||
|
||||
// Err logs a message with severity Err, ignoring the severity
|
||||
// passed to New.
|
||||
func (w *writer) Err(m string) error {
|
||||
return w.queueWrite(Err, w.tag, m)
|
||||
}
|
||||
|
||||
// Warning logs a message with severity Warning, ignoring the
|
||||
// severity passed to New.
|
||||
func (w *writer) Warning(m string) error {
|
||||
return w.queueWrite(Warning, w.tag, m)
|
||||
}
|
||||
|
||||
// Notice logs a message with severity Notice, ignoring the
|
||||
// severity passed to New.
|
||||
func (w *writer) Notice(m string) error {
|
||||
return w.queueWrite(Notice, w.tag, m)
|
||||
}
|
||||
|
||||
// Info logs a message with severity Info, ignoring the severity
|
||||
// passed to New.
|
||||
func (w *writer) Info(m string) error {
|
||||
return w.queueWrite(Info, w.tag, m)
|
||||
}
|
||||
|
||||
// Debug logs a message with severity Debug, ignoring the severity
|
||||
// passed to New.
|
||||
func (w *writer) Debug(m string) error {
|
||||
return w.queueWrite(Debug, w.tag, m)
|
||||
}
|
||||
|
||||
func (w *writer) queueWrite(p Priority, tag, s string) error {
|
||||
for w.parent != nil {
|
||||
w = w.parent
|
||||
}
|
||||
|
||||
select {
|
||||
case w.msgs <- &msg{p: p, tag: tag, msg: s}:
|
||||
default:
|
||||
return errors.New("queue full or writer closed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *writer) writeAndRetry(p Priority, tag, s string) (int, error) {
|
||||
if len(s) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
pr := (w.priority & facilityMask) | (p & severityMask)
|
||||
|
||||
if w.conn != nil {
|
||||
n, err := w.write(pr, tag, s)
|
||||
if err == nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
Logger.Errorf("syslog write failed: %s", err)
|
||||
}
|
||||
if err := w.connect(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return w.write(pr, tag, s)
|
||||
}
|
||||
|
||||
// write generates and writes a syslog formatted string. The
|
||||
// format is as follows: <PRI>TIMESTAMP HOSTNAME TAG[PID]: MSG
|
||||
func (w *writer) write(p Priority, tag, msg string) (int, error) {
|
||||
s := w.formatter.Format(p, time.Now(), w.hostname, tag, msg)
|
||||
// ensure it ends in a \n
|
||||
if !strings.HasSuffix(s, "\n") {
|
||||
s = s + "\n"
|
||||
}
|
||||
_, err := w.conn.Write([]byte(s))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// return len(msg), since we want to behave as an io.Writer
|
||||
return len(msg), nil
|
||||
}
|
||||
|
||||
func (w *writer) WithTag(tag string) Writer {
|
||||
return &writer{
|
||||
hostname: w.hostname,
|
||||
tag: tag,
|
||||
priority: w.priority,
|
||||
parent: w,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *writer) WithPriority(priority Priority) Writer {
|
||||
if !validPriority(priority) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &writer{
|
||||
hostname: w.hostname,
|
||||
tag: w.tag,
|
||||
priority: priority,
|
||||
parent: w,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *writer) run() {
|
||||
Logger.Infof("run()")
|
||||
defer func() {
|
||||
Logger.Infof("exiting syslog writer loop")
|
||||
if w.conn != nil {
|
||||
w.conn.Close()
|
||||
}
|
||||
close(w.done)
|
||||
}()
|
||||
|
||||
if err := w.connect(); err != nil {
|
||||
switch err.(type) {
|
||||
case *net.ParseError, *net.AddrError:
|
||||
Logger.Errorf("could not connect to syslog server (will not try again): %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
Logger.Errorf("error connecting to syslog server: %s", err)
|
||||
}
|
||||
|
||||
close(w.running)
|
||||
|
||||
for m := range w.msgs {
|
||||
for _, s := range strings.SplitAfter(m.msg, "\n") {
|
||||
if _, err := w.writeAndRetry(m.p, m.tag, s); err != nil {
|
||||
Logger.Errorf("could not write syslog message: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
278
vendor/github.com/vmware/vic/pkg/log/syslog/writer_test.go
generated
vendored
Normal file
278
vendor/github.com/vmware/vic/pkg/log/syslog/writer_test.go
generated
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestWriterReconnect(t *testing.T) {
|
||||
dn := &mockNetDialer{}
|
||||
dn.On("dial").Return(nil, assert.AnError)
|
||||
w := newWriter(priority, tag, "", dn, nil)
|
||||
|
||||
go w.run()
|
||||
<-w.running
|
||||
|
||||
calls := []func(string) error{
|
||||
w.Emerg,
|
||||
w.Crit,
|
||||
w.Err,
|
||||
w.Warning,
|
||||
w.Info,
|
||||
w.Debug,
|
||||
}
|
||||
for _, f := range calls {
|
||||
err := f("test")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
w.Close()
|
||||
|
||||
dn.AssertNumberOfCalls(t, "dial", 1+len(calls))
|
||||
}
|
||||
|
||||
func TestWriterWrite(t *testing.T) {
|
||||
msg := "foo"
|
||||
|
||||
f := &mockFormatter{}
|
||||
f.On("Format", priority, mock.Anything, "host", tag, msg).Return("test")
|
||||
|
||||
a := &MockAddr{}
|
||||
a.On("String").Return("host:123")
|
||||
|
||||
c := &MockNetConn{}
|
||||
c.On("LocalAddr").Return(a)
|
||||
c.On("Write", []byte("test\n")).Return(len(msg), nil)
|
||||
c.On("Close").Return(nil)
|
||||
|
||||
dn := &mockNetDialer{}
|
||||
dn.On("dial").Return(c, nil)
|
||||
|
||||
w := newWriter(priority, tag, "", dn, f)
|
||||
n, err := w.Write([]byte(msg))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(msg), n)
|
||||
|
||||
go w.run()
|
||||
<-w.running
|
||||
|
||||
w.Close()
|
||||
|
||||
c.AssertExpectations(t)
|
||||
dn.AssertNumberOfCalls(t, "dial", 1)
|
||||
}
|
||||
|
||||
func TestMaxLogBuffer(t *testing.T) {
|
||||
f := &mockFormatter{}
|
||||
|
||||
dn := &mockNetDialer{}
|
||||
c := &MockNetConn{}
|
||||
a := &MockAddr{}
|
||||
a.On("String").Return("foo")
|
||||
c.On("LocalAddr").Return(a)
|
||||
c.On("Close").Return(nil)
|
||||
|
||||
dn.On("dial").Return(c, nil)
|
||||
w := newWriter(priority, tag, "", dn, f)
|
||||
|
||||
for i := 0; i < maxLogBuffer+1; i++ {
|
||||
msg := fmt.Sprintf("%d", i)
|
||||
f.On("Format", priority, mock.Anything, "", tag, msg).Return(msg)
|
||||
c.On("Write", []byte(msg+"\n")).Return(len(msg), nil)
|
||||
w.Write([]byte(msg))
|
||||
}
|
||||
|
||||
go w.run()
|
||||
|
||||
<-w.running
|
||||
|
||||
w.Close()
|
||||
|
||||
for i := 0; i < maxLogBuffer; i++ {
|
||||
if !f.AssertCalled(t, "Format", priority, mock.Anything, "", tag, fmt.Sprintf("%d", i)) ||
|
||||
!c.AssertCalled(t, "Write", []byte(fmt.Sprintf("%d\n", i))) {
|
||||
}
|
||||
}
|
||||
|
||||
f.AssertNumberOfCalls(t, "Format", maxLogBuffer)
|
||||
f.AssertNotCalled(t, "Format", priority, mock.Anything, "", tag, fmt.Sprintf("%d", maxLogBuffer))
|
||||
}
|
||||
|
||||
func TestWriterReconnectWrite(t *testing.T) {
|
||||
dn := &mockNetDialer{}
|
||||
c := &MockNetConn{}
|
||||
a := &MockAddr{}
|
||||
a.On("String").Return("addr:123")
|
||||
c.On("LocalAddr").Return(a)
|
||||
c.On("Close").Return(nil)
|
||||
|
||||
dn.On("dial").Return(nil, assert.AnError)
|
||||
f := &mockFormatter{}
|
||||
w := newWriter(priority, tag, "", dn, f)
|
||||
|
||||
go w.run()
|
||||
<-w.running
|
||||
|
||||
dn.AssertNumberOfCalls(t, "dial", 1)
|
||||
|
||||
dn = &mockNetDialer{}
|
||||
dn.On("dial").Return(c, nil)
|
||||
w.dialer = dn
|
||||
|
||||
f.On("Format", priority, mock.Anything, "addr", tag, "test").Return("test")
|
||||
c.On("Write", []byte("test\n")).Return(len("test"), nil)
|
||||
|
||||
w.Write([]byte("test"))
|
||||
w.Close()
|
||||
|
||||
dn.AssertNumberOfCalls(t, "dial", 1)
|
||||
c.AssertNumberOfCalls(t, "Write", 1) // 1 call to writer.write
|
||||
f.AssertNumberOfCalls(t, "Format", 1)
|
||||
}
|
||||
|
||||
func TestWriterReconnectWriteError(t *testing.T) {
|
||||
dn := &mockNetDialer{}
|
||||
c := &MockNetConn{}
|
||||
a := &MockAddr{}
|
||||
a.On("String").Return("addr:123")
|
||||
c.On("LocalAddr").Return(a)
|
||||
c.On("Close").Return(nil)
|
||||
|
||||
dn.On("dial").Return(c, nil)
|
||||
f := &mockFormatter{}
|
||||
w := newWriter(priority, tag, "", dn, f)
|
||||
|
||||
go w.run()
|
||||
<-w.running
|
||||
|
||||
dn.AssertNumberOfCalls(t, "dial", 1)
|
||||
|
||||
f.On("Format", priority, mock.Anything, "addr", tag, "test").Return("test")
|
||||
c.On("Write", []byte("test\n")).Return(0, assert.AnError)
|
||||
|
||||
w.Write([]byte("test"))
|
||||
|
||||
w.Close()
|
||||
|
||||
f.AssertExpectations(t)
|
||||
c.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestWriterWithTag(t *testing.T) {
|
||||
f := &mockFormatter{}
|
||||
f.On("Format", priority, mock.Anything, "addr", "child", "child").Return("child")
|
||||
f.On("Format", priority, mock.Anything, "addr", "gchild", "gchild").Return("gchild")
|
||||
|
||||
dn := &mockNetDialer{}
|
||||
c := &MockNetConn{}
|
||||
a := &MockAddr{}
|
||||
a.On("String").Return("addr:123")
|
||||
c.On("LocalAddr").Return(a)
|
||||
c.On("Close").Return(nil)
|
||||
c.On("Write", []byte("child\n")).Return(len("child"), nil)
|
||||
c.On("Write", []byte("gchild\n")).Return(len("gchild"), nil)
|
||||
|
||||
dn.On("dial").Return(c, nil)
|
||||
|
||||
w := newWriter(priority, tag, "", dn, f)
|
||||
|
||||
child := w.WithTag("child")
|
||||
child.Write([]byte("child"))
|
||||
|
||||
gchild := child.WithTag("gchild")
|
||||
gchild.Write([]byte("gchild"))
|
||||
|
||||
go w.run()
|
||||
<-w.running
|
||||
|
||||
child.Close()
|
||||
gchild.Close()
|
||||
|
||||
select {
|
||||
case <-w.done:
|
||||
default:
|
||||
assert.FailNow(t, "parent writer is not closed by child Close call")
|
||||
}
|
||||
|
||||
f.AssertExpectations(t)
|
||||
c.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestWriterWithPriority(t *testing.T) {
|
||||
f := &mockFormatter{}
|
||||
f.On("Format", Err|Daemon, mock.Anything, "addr", tag, "err").Return("err")
|
||||
f.On("Format", Debug|Daemon, mock.Anything, "addr", tag, "debug").Return("debug")
|
||||
|
||||
dn := &mockNetDialer{}
|
||||
c := &MockNetConn{}
|
||||
a := &MockAddr{}
|
||||
a.On("String").Return("addr:123")
|
||||
c.On("LocalAddr").Return(a)
|
||||
c.On("Close").Return(nil)
|
||||
c.On("Write", []byte("err\n")).Return(len("err"), nil)
|
||||
c.On("Write", []byte("debug\n")).Return(len("debug"), nil)
|
||||
|
||||
dn.On("dial").Return(c, nil)
|
||||
|
||||
w := newWriter(priority, tag, "", dn, f)
|
||||
|
||||
errw := w.WithPriority(Err | Daemon)
|
||||
errw.Write([]byte("err"))
|
||||
|
||||
debugw := errw.WithPriority(Debug | Daemon)
|
||||
debugw.Write([]byte("debug"))
|
||||
|
||||
go w.run()
|
||||
<-w.running
|
||||
|
||||
errw.Close()
|
||||
|
||||
select {
|
||||
case <-w.done:
|
||||
default:
|
||||
assert.FailNow(t, "parent writer is not closed by child Close call")
|
||||
}
|
||||
|
||||
f.AssertExpectations(t)
|
||||
c.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestWriterInitialConnectError(t *testing.T) {
|
||||
|
||||
var tests = []error{
|
||||
&net.ParseError{},
|
||||
&net.AddrError{},
|
||||
}
|
||||
|
||||
for _, e := range tests {
|
||||
dn := &mockNetDialer{}
|
||||
dn.On("dial").Return(nil, e)
|
||||
|
||||
w := newWriter(priority, tag, "", dn, &mockFormatter{})
|
||||
w.run()
|
||||
|
||||
select {
|
||||
case <-w.running:
|
||||
assert.FailNow(t, "writer should not run when connect() fails initially")
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
63
vendor/github.com/vmware/vic/pkg/log/text_formatter.go
generated
vendored
Normal file
63
vendor/github.com/vmware/vic/pkg/log/text_formatter.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package log
|
||||
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// level strings padded to match the length of the longest level,
|
||||
// which is "UNKNOWN" currently. Indexed according to levels in
|
||||
// logrus, e.g. levelStrs[logrus.InfoLevel] == "INFO ".
|
||||
var levelStrs = []string{
|
||||
"PANIC",
|
||||
"FATAL",
|
||||
"ERROR",
|
||||
"WARN ",
|
||||
"INFO ",
|
||||
"DEBUG",
|
||||
}
|
||||
|
||||
const unknownLevel = "UNKWN"
|
||||
|
||||
type TextFormatter struct {
|
||||
// TimestampFormat is the format used to print the timestamp. By default
|
||||
// an RFC3339 timestamp is used.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
// NewTextFormatter returns a text formatter
|
||||
func NewTextFormatter() *TextFormatter {
|
||||
return &TextFormatter{
|
||||
TimestampFormat: "Jan _2 2006 15:04:05.000Z07:00",
|
||||
}
|
||||
}
|
||||
|
||||
func levelToString(level logrus.Level) string {
|
||||
if level <= logrus.DebugLevel {
|
||||
return levelStrs[level]
|
||||
}
|
||||
|
||||
return unknownLevel
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
t := f.timeStamp(entry)
|
||||
l := levelToString(entry.Level)
|
||||
|
||||
return []byte(t + " " + l + " " + entry.Message + "\n"), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) timeStamp(entry *logrus.Entry) string {
|
||||
return entry.Time.Format(f.TimestampFormat)
|
||||
}
|
||||
136
vendor/github.com/vmware/vic/pkg/log/text_formatter_test.go
generated
vendored
Normal file
136
vendor/github.com/vmware/vic/pkg/log/text_formatter_test.go
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
// Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func BenchmarkFormatNonEmpty(b *testing.B) {
|
||||
f := NewTextFormatter()
|
||||
e := &logrus.Entry{
|
||||
Time: time.Now(),
|
||||
Level: logrus.InfoLevel,
|
||||
Message: "the quick brown fox jumps over the lazy dog",
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
f.Format(e)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFormatEmpty(b *testing.B) {
|
||||
f := NewTextFormatter()
|
||||
e := &logrus.Entry{
|
||||
Time: time.Now(),
|
||||
Level: logrus.InfoLevel,
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
f.Format(e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatEmpty(t *testing.T) {
|
||||
ti := time.Now()
|
||||
e := &logrus.Entry{Time: ti, Level: logrus.InfoLevel}
|
||||
f := NewTextFormatter()
|
||||
|
||||
b, err := f.Format(e)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, fmt.Sprintf("%s %s \n", ti.Format(f.TimestampFormat), levelToString(e.Level)), string(b))
|
||||
}
|
||||
|
||||
func TestFormatNonEmpty(t *testing.T) {
|
||||
ti := time.Now()
|
||||
m := "foo bar baz"
|
||||
e := &logrus.Entry{Time: ti, Level: logrus.InfoLevel, Message: m}
|
||||
f := NewTextFormatter()
|
||||
|
||||
b, err := f.Format(e)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, fmt.Sprintf("%s %s %s\n", ti.Format(f.TimestampFormat), levelToString(e.Level), m), string(b))
|
||||
|
||||
// test with multiple lines
|
||||
pre := fmt.Sprintf("%s %s ", ti.Format(f.TimestampFormat), levelToString(e.Level))
|
||||
var tests = []struct {
|
||||
in string
|
||||
out []string
|
||||
}{
|
||||
{
|
||||
"foo",
|
||||
[]string{
|
||||
pre + "foo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"\n",
|
||||
[]string{
|
||||
pre,
|
||||
"",
|
||||
},
|
||||
},
|
||||
{
|
||||
"foo\n",
|
||||
[]string{
|
||||
pre + "foo",
|
||||
"",
|
||||
},
|
||||
},
|
||||
{
|
||||
"\nfoo\n",
|
||||
[]string{
|
||||
pre + "",
|
||||
"foo",
|
||||
"",
|
||||
},
|
||||
},
|
||||
{
|
||||
"foo\n",
|
||||
[]string{
|
||||
pre + "foo",
|
||||
"",
|
||||
},
|
||||
},
|
||||
{
|
||||
"foo \nbar\n baz ",
|
||||
[]string{
|
||||
pre + "foo ",
|
||||
"bar",
|
||||
" baz ",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for idx, te := range tests {
|
||||
e.Message = te.in
|
||||
b, err = f.Format(e)
|
||||
assert.NoError(t, err)
|
||||
s := bufio.NewScanner(strings.NewReader(string(b)))
|
||||
i := 0
|
||||
for s.Scan() {
|
||||
assert.True(t, i < len(te.out), "case %d", idx)
|
||||
assert.Equal(t, te.out[i], s.Text(), "case %d", idx)
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user