fix: unit tests (#69)

* fix: unit tests

* chore: update release notes
This commit is contained in:
silenceqi 2025-01-04 18:30:48 +08:00 committed by GitHub
parent 635abc6524
commit 8a27cd4389
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 132 deletions

View File

@ -17,6 +17,7 @@ Information about release notes of INFINI Console is provided here.
### Bug fix
- Fixed query thread pool metrics when cluster uuid is empty
- Fixed unit tests
### Improvements
- Optimize UI of agent list when its columns are overflow.

View File

@ -102,7 +102,7 @@ func TestCreateRule( t *testing.T) {
},
},
Channels: NotificationConfig{
Channels: &NotificationConfig{
Normal: []Channel{
{Name: "钉钉", Type: ChannelWebhook, Webhook: &CustomWebhook{
HeaderParams: map[string]string{

View File

@ -34,8 +34,11 @@ import (
func TestGetMetricParams(t *testing.T) {
handler:=APIHandler{}
req:=http.Request{}
bucketSize, min, max, err:=handler.getMetricRangeAndBucketSize(&req,60,15)
req, err :=http.NewRequest("GET","https://infinilabs.com/api/?bucket_size=1m",nil)
if err != nil {
t.Fatal(err)
}
bucketSize, min, max, err:=handler.GetMetricRangeAndBucketSize(req,"", "",15)
fmt.Println(bucketSize)
fmt.Println(util.FormatUnixTimestamp(min/1000))//2022-01-27 15:28:57

View File

@ -1,115 +0,0 @@
// Copyright (C) INFINI Labs & INFINI LIMITED.
//
// The INFINI Console is offered under the GNU Affero General Public License v3.0
// and as commercial software.
//
// For commercial licensing, contact us at:
// - Website: infinilabs.com
// - Email: hello@infini.ltd
//
// Open Source licensed under AGPL V3:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package v1
import (
"fmt"
"infini.sh/framework/core/util"
"infini.sh/framework/modules/elastic/common"
"net/http"
"testing"
"time"
)
func TestGetMetricParams(t *testing.T) {
handler:=APIHandler{}
req:=http.Request{}
bucketSize, min, max, err:=handler.getMetricRangeAndBucketSize(&req,60,15)
fmt.Println(bucketSize)
fmt.Println(util.FormatUnixTimestamp(min/1000))//2022-01-27 15:28:57
fmt.Println(util.FormatUnixTimestamp(max/1000))//2022-01-27 15:28:57
fmt.Println(time.Now())//2022-01-27 15:28:57
fmt.Println(bucketSize, min, max, err)
}
func TestConvertBucketItemsToAggQueryParams(t *testing.T) {
bucketItem:=common.BucketItem{}
bucketItem.Key="key1"
bucketItem.Type=common.TermsBucket
bucketItem.Parameters=map[string]interface{}{}
bucketItem.Parameters["field"]="metadata.labels.cluster_id"
bucketItem.Parameters["size"]=2
nestBucket:=common.BucketItem{}
nestBucket.Key="key2"
nestBucket.Type=common.DateHistogramBucket
nestBucket.Parameters=map[string]interface{}{}
nestBucket.Parameters["field"]="timestamp"
nestBucket.Parameters["calendar_interval"]="1d"
nestBucket.Parameters["time_zone"]="+08:00"
leafBucket:=common.NewBucketItem(common.TermsBucket,util.MapStr{
"size":5,
"field":"payload.elasticsearch.cluster_health.status",
})
leafBucket.Key="key3"
metricItems:=[]*common.MetricItem{}
var bucketSizeStr ="10s"
metricItem:=newMetricItem("cluster_summary", 2, "cluster")
metricItem.Key="key4"
metricItem.AddLine("Indexing","Total Indexing","Number of documents being indexed for primary and replica shards.","group1",
"payload.elasticsearch.index_stats.total.indexing.index_total","max",bucketSizeStr,"doc/s","num","0,0.[00]","0,0.[00]",false,true)
metricItem.AddLine("Search","Total Search","Number of search requests being executed across primary and replica shards. A single search can run against multiple shards!","group1",
"payload.elasticsearch.index_stats.total.search.query_total","max",bucketSizeStr,"query/s","num","0,0.[00]","0,0.[00]",false,true)
metricItems=append(metricItems,metricItem)
nestBucket.AddNestBucket(leafBucket)
nestBucket.Metrics=metricItems
bucketItem.Buckets=[]*common.BucketItem{}
bucketItem.Buckets=append(bucketItem.Buckets,&nestBucket)
aggs:=ConvertBucketItemsToAggQuery([]*common.BucketItem{&bucketItem},nil)
fmt.Println(util.MustToJSON(aggs))
response:="{ \"took\": 37, \"timed_out\": false, \"_shards\": { \"total\": 1, \"successful\": 1, \"skipped\": 0, \"failed\": 0 }, \"hits\": { \"total\": { \"value\": 10000, \"relation\": \"gte\" }, \"max_score\": null, \"hits\": [] }, \"aggregations\": { \"key1\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [ { \"key\": \"c7pqhptj69a0sg3rn05g\", \"doc_count\": 80482, \"key2\": { \"buckets\": [ { \"key_as_string\": \"2022-01-28T00:00:00.000+08:00\", \"key\": 1643299200000, \"doc_count\": 14310, \"c7qi5hii4h935v9bs91g\": { \"value\": 15680 }, \"key3\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [] }, \"c7qi5hii4h935v9bs920\": { \"value\": 2985 } }, { \"key_as_string\": \"2022-01-29T00:00:00.000+08:00\", \"key\": 1643385600000, \"doc_count\": 66172, \"c7qi5hii4h935v9bs91g\": { \"value\": 106206 }, \"key3\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [] }, \"c7qi5hii4h935v9bs920\": { \"value\": 20204 }, \"c7qi5hii4h935v9bs91g_deriv\": { \"value\": 90526 }, \"c7qi5hii4h935v9bs920_deriv\": { \"value\": 17219 } } ] } }, { \"key\": \"c7qi42ai4h92sksk979g\", \"doc_count\": 660, \"key2\": { \"buckets\": [ { \"key_as_string\": \"2022-01-29T00:00:00.000+08:00\", \"key\": 1643385600000, \"doc_count\": 660, \"c7qi5hii4h935v9bs91g\": { \"value\": 106206 }, \"key3\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [] }, \"c7qi5hii4h935v9bs920\": { \"value\": 20204 } } ] } } ] } } }"
res:=SearchResponse{}
util.FromJSONBytes([]byte(response),&res)
fmt.Println(response)
groupKey:="key1"
metricLabelKey:="key2"
metricValueKey:="c7qi5hii4h935v9bs920"
data:=ParseAggregationResult(int(10),res.Aggregations,groupKey,metricLabelKey,metricValueKey)
fmt.Println(data)
}
func TestConvertBucketItems(t *testing.T) {
response:="{ \"took\": 8, \"timed_out\": false, \"_shards\": { \"total\": 1, \"successful\": 1, \"skipped\": 0, \"failed\": 0 }, \"hits\": { \"total\": { \"value\": 81, \"relation\": \"eq\" }, \"max_score\": null, \"hits\": [] }, \"aggregations\": { \"c7v2gm3i7638vvo4pv80\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [ { \"key\": \"c7uv7p3i76360kgdmpb0\", \"doc_count\": 81, \"c7v2gm3i7638vvo4pv8g\": { \"buckets\": [ { \"key_as_string\": \"2022-02-05T00:00:00.000+08:00\", \"key\": 1643990400000, \"doc_count\": 81, \"c7v2gm3i7638vvo4pv90\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [ { \"key\": \"yellow\", \"doc_count\": 81 } ] } } ] } } ] } } }"
res:=SearchResponse{}
util.FromJSONBytes([]byte(response),&res)
data:=ParseAggregationBucketResult(int(10),res.Aggregations,"c7v2gm3i7638vvo4pv80","c7v2gm3i7638vvo4pv8g","c7v2gm3i7638vvo4pv90", func() {
})
fmt.Println(data)
}

View File

@ -30,7 +30,10 @@ package elasticsearch
import (
"fmt"
"infini.sh/console/model/alerting"
"infini.sh/console/model/insight"
"infini.sh/framework/core/elastic"
"infini.sh/framework/core/util"
"infini.sh/framework/modules/elastic/adapter/elasticsearch"
"net/http"
"sort"
"testing"
@ -77,12 +80,15 @@ func TestEngine( t *testing.T) {
},
Metrics: alerting.Metric{
PeriodInterval: "1m",
Items: []alerting.MetricItem{
{Name: "a", Field: "payload.elasticsearch.node_stats.fs.total.free_in_bytes", Statistic: "min", Group: []string{"metadata.labels.cluster_id", "metadata.labels.node_id"}},
{Name: "b", Field: "payload.elasticsearch.node_stats.fs.total.total_in_bytes", Statistic: "max", Group: []string{"metadata.labels.cluster_id", "metadata.labels.node_id"}},
Metric: insight.Metric{
BucketSize: "1m",
Items: []insight.MetricItem{
{Name: "a", Field: "payload.elasticsearch.node_stats.fs.total.free_in_bytes", Statistic: "min"},
{Name: "b", Field: "payload.elasticsearch.node_stats.fs.total.total_in_bytes", Statistic: "max"},
},
Formula: "a/b*100",
},
Formula: "a/b*100",
//Expression: "min(fs.free_in_bytes)/max(fs.total_in_bytes)*100",
},
Conditions: alerting.Condition{
@ -93,7 +99,7 @@ func TestEngine( t *testing.T) {
},
},
Channels: alerting.NotificationConfig{
Channels: &alerting.NotificationConfig{
Normal: []alerting.Channel{
{Name: "钉钉", Type: alerting.ChannelWebhook, Webhook: &alerting.CustomWebhook{
HeaderParams: map[string]string{
@ -139,7 +145,7 @@ func TestEngine( t *testing.T) {
func TestGenerateAgg(t *testing.T) {
eng := &Engine{}
agg := eng.generateAgg(&alerting.MetricItem{
agg := eng.generateAgg(&insight.MetricItem{
Name: "a",
Field: "cpu.percent",
Statistic: "p99",
@ -199,13 +205,23 @@ func TestGeneratePercentilesAggQuery(t *testing.T) {
// EscalationThrottlePeriod: "30m",
// },
//}
cfg := elastic.ElasticsearchConfig{}
cfg.ID = "test"
esClient := elasticsearch.ESAPIV7{}
esClient.Elasticsearch = cfg.ID
esClient.Version = elastic.Version{
Number: "7.10.2",
Major: 7,
Distribution: elastic.Elasticsearch,
}
elastic.UpdateClient(cfg, &esClient)
rule := alerting.Rule{
ID: util.GetUUID(),
Created: time.Now(),
Updated: time.Now(),
Enabled: true,
Resource: alerting.Resource{
ID: "c8i18llath2blrusdjng",
ID: cfg.ID,
Type: "elasticsearch",
Objects: []string{".infini_metrics*"},
TimeField: "timestamp",
@ -225,12 +241,14 @@ func TestGeneratePercentilesAggQuery(t *testing.T) {
},
Metrics: alerting.Metric{
PeriodInterval: "1m",
Items: []alerting.MetricItem{
{Name: "a", Field: "payload.elasticsearch.index_stats.total.search.query_total", Statistic: "rate", Group: []string{"metadata.labels.cluster_id"}},
{Name: "b", Field: "payload.elasticsearch.index_stats.total.search.query_time_in_millis", Statistic: "rate", Group: []string{"metadata.labels.cluster_id"}},
Metric: insight.Metric{
BucketSize: "1m",
Items: []insight.MetricItem{
{Name: "a", Field: "payload.elasticsearch.index_stats.total.search.query_total", Statistic: "rate"},
{Name: "b", Field: "payload.elasticsearch.index_stats.total.search.query_time_in_millis", Statistic: "rate"},
},
Formula: "b/a",
},
Formula: "b/a",
},
Conditions: alerting.Condition{
Operator: "any",
@ -239,7 +257,7 @@ func TestGeneratePercentilesAggQuery(t *testing.T) {
},
},
Channels: alerting.NotificationConfig{
Channels: &alerting.NotificationConfig{
Normal: []alerting.Channel{
{Name: "钉钉", Type: alerting.ChannelWebhook, Webhook: &alerting.CustomWebhook{
HeaderParams: map[string]string{