mirror of
https://github.com/hanzoai/o11y.git
synced 2026-10-15 12:58:33 +00:00
* chore: custom notifiers in alert manager * chore: lint fixs * chore: fix email linter * chore: added tracing to msteamsv2 notifier * feat: alert manager template to template title and notification body * chore: updated test name + code for timeout errors * chore: added utils for using variables with $ notation * chore: exposed templates for alertmanager types * feat: added preprocessor for alert templater * chore: hooked preProcess function in expandTitle and body, added labels and annotations in alertdata * chore: fix lint issues * chore: added handling for missing variable used in template * feat: converted alerttemplater to interface and updated tests * refactor: added extractCommonKV instead of 2 different functions * test: fix preprocessor test case * feat: added support for and in templating * chore: lint fix * chore: renamed the interface * chore: added test for missing function * refactor: test case and sb related changed * refactor: comments and test improvements * chore: lint fix * chore: updated comments * feat: added basic html markdown templater * chore: updated newline to markdown format * feat: slack blockkit renderer using goldmark * test: added test for html rendering * feat: integrated slack blockit in markdownrenderer package and removed plaintext format * chore: updated br with new line in test and logs added * refactor: review comments * refactor: lint fixes * chore: updated licenses for notifiers * chore: updated email notifier from upstream * feat: return single templating result from with flag for template type * fix: variables with symbols in template * feat: slack mrkdwn renderer * feat: custom raw html renderer to escape <no value> * chore: integrated slack mrkdwn renderer and added NoOp formatter * chore: removed notifier test files * fix: concurrent rendering in markdown renderer * refactor: changes as per internal review * chore: lint issue * chore: removed special handling for softline break * refactor: removed logger as markdown renderer dependency * refactor: changed markdown renderer from interface to package-level functions --------- Co-authored-by: Srikanth Chekuri <[email protected]>
146 lines
3.3 KiB
Go
146 lines
3.3 KiB
Go
package markdownrenderer
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
func jsonEqual(a, b string) bool {
|
|
var va, vb any
|
|
if err := json.Unmarshal([]byte(a), &va); err != nil {
|
|
return false
|
|
}
|
|
if err := json.Unmarshal([]byte(b), &vb); err != nil {
|
|
return false
|
|
}
|
|
ja, _ := json.Marshal(va)
|
|
jb, _ := json.Marshal(vb)
|
|
return string(ja) == string(jb)
|
|
}
|
|
|
|
func prettyJSON(s string) string {
|
|
var v any
|
|
if err := json.Unmarshal([]byte(s), &v); err != nil {
|
|
return s
|
|
}
|
|
b, _ := json.MarshalIndent(v, "", " ")
|
|
return string(b)
|
|
}
|
|
|
|
func TestRenderSlackBlockKit(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
markdown string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple paragraph",
|
|
markdown: "Hello world",
|
|
expected: `[
|
|
{
|
|
"type": "section",
|
|
"text": { "type": "mrkdwn", "text": "Hello world" }
|
|
}
|
|
]`,
|
|
},
|
|
{
|
|
name: "alert-themed with heading, list, and code block",
|
|
markdown: `# Alert Triggered
|
|
|
|
- Service: **checkout-api**
|
|
- Status: _critical_
|
|
|
|
` + "```" + `
|
|
error: connection timeout after 30s
|
|
` + "```",
|
|
expected: `[
|
|
{
|
|
"type": "section",
|
|
"text": { "type": "mrkdwn", "text": "*Alert Triggered*" }
|
|
},
|
|
{
|
|
"type": "rich_text",
|
|
"elements": [
|
|
{
|
|
"type": "rich_text_list", "style": "bullet", "indent": 0, "border": 0,
|
|
"elements": [
|
|
{ "type": "rich_text_section", "elements": [
|
|
{ "type": "text", "text": "Service: " },
|
|
{ "type": "text", "text": "checkout-api", "style": { "bold": true } }
|
|
]},
|
|
{ "type": "rich_text_section", "elements": [
|
|
{ "type": "text", "text": "Status: " },
|
|
{ "type": "text", "text": "critical", "style": { "italic": true } }
|
|
]}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "rich_text",
|
|
"elements": [
|
|
{
|
|
"type": "rich_text_preformatted",
|
|
"border": 0,
|
|
"elements": [
|
|
{ "type": "text", "text": "error: connection timeout after 30s" }
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := RenderSlackBlockKit(tt.markdown)
|
|
if err != nil {
|
|
t.Fatalf("Render error: %v", err)
|
|
}
|
|
|
|
if !json.Valid([]byte(got)) {
|
|
t.Fatalf("output is not valid JSON:\n%s", got)
|
|
}
|
|
|
|
if !jsonEqual(got, tt.expected) {
|
|
t.Errorf("JSON mismatch\n\nMarkdown:\n%s\n\nExpected:\n%s\n\nGot:\n%s",
|
|
tt.markdown, prettyJSON(tt.expected), prettyJSON(got))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRenderSlackMrkdwn(t *testing.T) {
|
|
markdown := `# Alert Triggered
|
|
|
|
- Service: **checkout-api**
|
|
- Status: _critical_
|
|
- Dashboard: [View Dashboard](https://example.com/dashboard)
|
|
|
|
| Metric | Value | Threshold |
|
|
| --- | --- | --- |
|
|
| Latency | 250ms | 100ms |
|
|
| Error Rate | 5.2% | 1% |
|
|
|
|
` + "```" + `
|
|
error: connection timeout after 30s
|
|
` + "```"
|
|
|
|
expected := "*Alert Triggered*\n\n" +
|
|
"• Service: *checkout-api*\n" +
|
|
"• Status: _critical_\n" +
|
|
"• Dashboard: <https://example.com/dashboard|View Dashboard>\n\n" +
|
|
"```\nMetric | Value | Threshold\n-----------|-------|----------\nLatency | 250ms | 100ms \nError Rate | 5.2% | 1% \n```\n\n" +
|
|
"```\nerror: connection timeout after 30s\n```\n\n"
|
|
|
|
got, err := RenderSlackMrkdwn(markdown)
|
|
if err != nil {
|
|
t.Fatalf("Render error: %v", err)
|
|
}
|
|
|
|
if got != expected {
|
|
t.Errorf("mrkdwn mismatch\n\nExpected:\n%q\n\nGot:\n%q", expected, got)
|
|
}
|
|
}
|