Skip to content

Commit

Permalink
Merge 46f8650 into 48ed634
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Mar 8, 2019
2 parents 48ed634 + 46f8650 commit 2490f59
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 17 deletions.
18 changes: 11 additions & 7 deletions hosts/app.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package hosts

import (
"os"
"io"
"text/template"

mkr "github.com/mackerelio/mackerel-client-go"
mackerel "github.com/mackerelio/mackerel-client-go"

"github.com/mackerelio/mkr/format"
"github.com/mackerelio/mkr/mackerelclient"
)

type hostApp struct {
cli *mkr.Client
client mackerelclient.Client

verbose bool

Expand All @@ -19,10 +21,12 @@ type hostApp struct {
statuses []string

format string

outStream io.Writer
}

func (ha *hostApp) run() error {
hosts, err := ha.cli.FindHosts(&mkr.FindHostsParam{
hosts, err := ha.client.FindHosts(&mackerel.FindHostsParam{
Name: ha.name,
Service: ha.service,
Roles: ha.roles,
Expand All @@ -38,9 +42,9 @@ func (ha *hostApp) run() error {
if err != nil {
return err
}
return t.Execute(os.Stdout, hosts)
return t.Execute(ha.outStream, hosts)
case ha.verbose:
return format.PrettyPrintJSON(os.Stdout, hosts)
return format.PrettyPrintJSON(ha.outStream, hosts)
default:
var hostsFormat []*format.Host
for _, host := range hosts {
Expand All @@ -55,6 +59,6 @@ func (ha *hostApp) run() error {
IPAddresses: host.IPAddresses(),
})
}
return format.PrettyPrintJSON(os.Stdout, hostsFormat)
return format.PrettyPrintJSON(ha.outStream, hostsFormat)
}
}
212 changes: 212 additions & 0 deletions hosts/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package hosts

import (
"bytes"
"testing"
"time"

"github.com/stretchr/testify/assert"

mackerel "github.com/mackerelio/mackerel-client-go"

"github.com/mackerelio/mkr/mackerelclient"
)

var (
sampleHost1 = &mackerel.Host{
ID: "foo",
Name: "sample.app1",
DisplayName: "Sample Host foo",
Status: mackerel.HostStatusWorking,
Roles: mackerel.Roles{
"SampleService": []string{"app"},
},
IsRetired: false,
CreatedAt: 1553000000,
Interfaces: []mackerel.Interface{
{
Name: "en0",
IPAddress: "10.0.0.1",
},
},
}
sampleHost2 = &mackerel.Host{
ID: "bar",
Name: "sample.app2",
DisplayName: "Sample Host bar",
Status: mackerel.HostStatusStandby,
Roles: mackerel.Roles{
"SampleService": []string{"db"},
},
IsRetired: false,
CreatedAt: 1552000000,
Interfaces: []mackerel.Interface{
{
Name: "eth0",
IPAddress: "10.0.1.2",
},
},
}
)

func TestHostApp_Run(t *testing.T) {
time.Local = time.FixedZone("Asia/Tokyo", 9*60*60)
defer func() { time.Local = nil }()
testCases := []struct {
id string
verbose bool
name string
service string
roles []string
statuses []string
format string
hosts []*mackerel.Host
expected string
}{
{
id: "default",
hosts: []*mackerel.Host{sampleHost1, sampleHost2},
expected: `[
{
"id": "foo",
"name": "sample.app1",
"displayName": "Sample Host foo",
"status": "working",
"roleFullnames": [
"SampleService:app"
],
"isRetired": false,
"createdAt": "2019-03-19T21:53:20+09:00",
"ipAddresses": {
"en0": "10.0.0.1"
}
},
{
"id": "bar",
"name": "sample.app2",
"displayName": "Sample Host bar",
"status": "standby",
"roleFullnames": [
"SampleService:db"
],
"isRetired": false,
"createdAt": "2019-03-08T08:06:40+09:00",
"ipAddresses": {
"eth0": "10.0.1.2"
}
}
]
`,
},
{
id: "verbose",
hosts: []*mackerel.Host{sampleHost1, sampleHost2},
verbose: true,
expected: `[
{
"id": "foo",
"name": "sample.app1",
"displayName": "Sample Host foo",
"type": "",
"status": "working",
"memo": "",
"roles": {
"SampleService": [
"app"
]
},
"isRetired": false,
"createdAt": 1553000000,
"meta": {},
"interfaces": [
{
"name": "en0",
"ipAddress": "10.0.0.1"
}
]
},
{
"id": "bar",
"name": "sample.app2",
"displayName": "Sample Host bar",
"type": "",
"status": "standby",
"memo": "",
"roles": {
"SampleService": [
"db"
]
},
"isRetired": false,
"createdAt": 1552000000,
"meta": {},
"interfaces": [
{
"name": "eth0",
"ipAddress": "10.0.1.2"
}
]
}
]
`,
},
{
id: "format",
hosts: []*mackerel.Host{sampleHost1, sampleHost2},
format: `{{range .}}{{.ID}} {{.Name}} {{.Status}} {{.CreatedAt}}{{"\n"}}{{end}}`,
expected: `foo sample.app1 working 1553000000
bar sample.app2 standby 1552000000
`,
},
{
id: "name",
hosts: []*mackerel.Host{},
name: "Sample.app",
expected: "null\n",
},
{
id: "service",
hosts: []*mackerel.Host{},
service: "SampleService",
expected: "null\n",
},
{
id: "roles",
hosts: []*mackerel.Host{},
roles: []string{"role1", "role2"},
expected: "null\n",
},
{
id: "statuses",
hosts: []*mackerel.Host{},
statuses: []string{mackerel.HostStatusPoweroff, mackerel.HostStatusMaintenance},
expected: "null\n",
},
}
for _, tc := range testCases {
client := mackerelclient.NewMockClient(
mackerelclient.MockFindHosts(func(param *mackerel.FindHostsParam) ([]*mackerel.Host, error) {
assert.Equal(t, tc.name, param.Name)
assert.Equal(t, tc.service, param.Service)
assert.Equal(t, tc.roles, param.Roles)
assert.Equal(t, tc.statuses, param.Statuses)
return tc.hosts, nil
}),
)
t.Run(tc.id, func(t *testing.T) {
out := new(bytes.Buffer)
app := &hostApp{
client: client,
verbose: tc.verbose,
name: tc.name,
service: tc.service,
roles: tc.roles,
statuses: tc.statuses,
format: tc.format,
outStream: out,
}
assert.NoError(t, app.run())
assert.Equal(t, tc.expected, out.String())
})
}
}
11 changes: 8 additions & 3 deletions hosts/command.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package hosts

import (
"github.com/mackerelio/mkr/mackerelclient"
"os"

cli "gopkg.in/urfave/cli.v1"

"github.com/mackerelio/mkr/mackerelclient"
)

// Command is definition of mkr hosts subcommand
Expand Down Expand Up @@ -34,13 +37,13 @@ var Command = cli.Command{
}

func doHosts(c *cli.Context) error {
cli, err := mackerelclient.New(c.GlobalString("conf"), c.GlobalString("apibase"))
client, err := mackerelclient.New(c.GlobalString("conf"), c.GlobalString("apibase"))
if err != nil {
return err
}

return (&hostApp{
cli: cli,
client: client,

verbose: c.Bool("verbose"),

Expand All @@ -50,5 +53,7 @@ func doHosts(c *cli.Context) error {
statuses: c.StringSlice("status"),

format: c.String("format"),

outStream: os.Stdout,
}).run()
}
8 changes: 8 additions & 0 deletions mackerelclient/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package mackerelclient

import mackerel "github.com/mackerelio/mackerel-client-go"

// Client represents a client of Mackerel API
type Client interface {
FindHosts(param *mackerel.FindHostsParam) ([]*mackerel.Host, error)
}
46 changes: 46 additions & 0 deletions mackerelclient/mock_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package mackerelclient

import mackerel "github.com/mackerelio/mackerel-client-go"

// MockClient represents a mock client of Mackerel API
type MockClient struct {
findHostsCallback func(param *mackerel.FindHostsParam) ([]*mackerel.Host, error)
}

// MockClientOption represents an option of mock client of Mackerel API
type MockClientOption func(*MockClient)

// NewMockClient creates a new mock client of Mackerel API
func NewMockClient(opts ...MockClientOption) *MockClient {
client := &MockClient{}
for _, opt := range opts {
client.ApplyOption(opt)
}
return client
}

// ApplyOption applies a mock client option
func (c *MockClient) ApplyOption(opt MockClientOption) {
opt(c)
}

type errCallbackNotFound string

func (err errCallbackNotFound) Error() string {
return string(err) + " callback not found"
}

// FindHosts ...
func (c *MockClient) FindHosts(param *mackerel.FindHostsParam) ([]*mackerel.Host, error) {
if c.findHostsCallback != nil {
return c.findHostsCallback(param)
}
return nil, errCallbackNotFound("FindHosts")
}

// MockFindHosts returns an option to set the callback of FindHosts
func MockFindHosts(callback func(param *mackerel.FindHostsParam) ([]*mackerel.Host, error)) MockClientOption {
return func(c *MockClient) {
c.findHostsCallback = callback
}
}
Loading

0 comments on commit 2490f59

Please sign in to comment.