diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..31eebca --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,32 @@ +--- +name: test + +on: + push: + branches: + - main + tags: + - v* + pull_request: +env: + DEBIAN_FRONTEND: noninteractive +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: golangci/golangci-lint-action@v3 + test: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: "1.19.x" + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - run: go test -v ./... diff --git a/charset/charset_test.go b/charset/charset_test.go index e57a9ba..a1b579d 100644 --- a/charset/charset_test.go +++ b/charset/charset_test.go @@ -28,8 +28,8 @@ func TestAdd(t *testing.T) { func TestDecoder(t *testing.T) { d := NewDecoder() - d.Register("192.0.2.1", "utf-8") - d.Register("192.0.2.2", "shift-jis") + _ = d.Register("192.0.2.1", "utf-8") + _ = d.Register("192.0.2.2", "shift-jis") t.Run("select utf-8", func(t *testing.T) { actual, err := d.Decode("192.0.2.1", []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f}) diff --git a/notification/queue.go b/notification/queue.go index 33cffc4..eebf142 100644 --- a/notification/queue.go +++ b/notification/queue.go @@ -11,10 +11,14 @@ import ( "github.com/mackerelio/mackerel-client-go" ) +type Client interface { + PostCheckReports(crs *mackerel.CheckReports) error +} + type Queue struct { q *list.List m sync.Mutex - client *mackerel.Client + client Client hostId string } @@ -25,7 +29,7 @@ type Item struct { } // NewQueue is needed mackerel client, host id. -func NewQueue(client *mackerel.Client, hostId string) *Queue { +func NewQueue(client Client, hostId string) *Queue { return &Queue{ q: list.New(), client: client, @@ -48,12 +52,12 @@ func (q *Queue) Dequeue(ctx context.Context) { item := e.Value.(Item) if q.client == nil { log.Printf("receive %q %q\n", item.Addr, item.Message) - return - } - err := q.send(item) - if err != nil { - log.Println(err) - return + } else { + err := q.send(item) + if err != nil { + log.Println(err) + return + } } q.m.Lock() q.q.Remove(e) diff --git a/notification/queue_test.go b/notification/queue_test.go new file mode 100644 index 0000000..a59700b --- /dev/null +++ b/notification/queue_test.go @@ -0,0 +1,131 @@ +package notification + +import ( + "bytes" + "context" + "fmt" + "io" + "log" + "os" + "strings" + "testing" + + "github.com/mackerelio/mackerel-client-go" +) + +type mockClient struct { + reports *mackerel.CheckReports +} + +func (m *mockClient) PostCheckReports(crs *mackerel.CheckReports) error { + m.reports = crs + return nil +} + +func TestRoundOffMessage(t *testing.T) { + log.SetOutput(io.Discard) + log.SetFlags(0) + defer func() { + log.SetOutput(os.Stderr) + log.SetFlags(log.LstdFlags) + }() + + client := &mockClient{} + + msg := strings.Repeat("a", 2048) + + q := NewQueue(client, "") + q.Enqueue(Item{OccurredAt: 1, Addr: "192.0.2.1", Message: msg}) + ctx := context.Background() + q.Dequeue(ctx) + + report := client.reports.Reports[0] + + if len(report.Message) != 1024 { + t.Error("invalid round Message") + } +} + +func TestQueue(t *testing.T) { + client := &mockClient{} + q := NewQueue(client, "") + q.Enqueue(Item{OccurredAt: 1, Addr: "192.0.2.1", Message: "message"}) + ctx := context.Background() + q.Dequeue(ctx) + + report := client.reports.Reports[0] + + if report.Name != "sabatrapd 192.0.2.1" { + t.Error("invalid Name") + } + if report.Status != "WARNING" { + t.Error("invalid Status") + } + if report.Message != "message" { + t.Error("invalid Message") + } + if report.OccurredAt != 1 { + t.Error("invalid OccurredAt") + } +} + +func DryRunQueue() { + q := NewQueue(nil, "") + q.Enqueue(Item{OccurredAt: 1, Addr: "192.0.2.1", Message: "message"}) + + ctx := context.Background() + q.Dequeue(ctx) +} + +func TestDryRunQueue(t *testing.T) { + var buf bytes.Buffer + log.SetOutput(&buf) + log.SetFlags(0) + defer func() { + log.SetOutput(os.Stderr) + log.SetFlags(log.LstdFlags) + }() + DryRunQueue() + actual := buf.String() + expected := `receive "192.0.2.1" "message"` + "\n" + if actual != expected { + t.Errorf("log is invalid. get %q, want %q", actual, expected) + } +} + +type mockErrorClient struct { +} + +func (m *mockErrorClient) PostCheckReports(crs *mackerel.CheckReports) error { + return fmt.Errorf("error %s", crs.Reports[0].Message) +} + +func QueueClientError(t *testing.T) { + client := &mockErrorClient{} + q := NewQueue(client, "") + q.Enqueue(Item{OccurredAt: 1, Addr: "192.0.2.1", Message: "message"}) + ctx := context.Background() + q.Dequeue(ctx) + + actual := q.q.Len() + expected := 1 + if actual != expected { + t.Errorf("queue length is invalid. want %d, get %d", expected, actual) + } +} + +func TestQueueClientError(t *testing.T) { + var buf bytes.Buffer + log.SetOutput(&buf) + log.SetFlags(0) + defer func() { + log.SetOutput(os.Stderr) + log.SetFlags(log.LstdFlags) + }() + QueueClientError(t) + actual := buf.String() + expected := `error message` + "\n" + if actual != expected { + t.Errorf("log is invalid. get %q, want %q", actual, expected) + } +}