• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / reporting / 837242630

pending completion
837242630

Pull #130

gitlab-ci

Krzysztof Jaskiewicz
test: acceptance test for geo queries
Pull Request #130: support for geolocation queries

52 of 56 new or added lines in 3 files covered. (92.86%)

12 existing lines in 2 files now uncovered.

2861 of 3355 relevant lines covered (85.28%)

17.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.72
/model/aggregations.go
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
package model
16

17
import (
18
        validation "github.com/go-ozzo/ozzo-validation/v4"
19
        "github.com/pkg/errors"
20
)
21

22
const (
23
        defaultAggregationLimit = 10
24
        maxAggregationTerms     = 100
25
        maxNestedAggregations   = 5
26
)
27

28
type AggregateParams struct {
29
        Aggregations         []AggregationTerm     `json:"aggregations"`
30
        Filters              []FilterPredicate     `json:"filters"`
31
        GeoDistanceFilter    *GeoDistanceFilter    `json:"geo_distance_filter"`
32
        GeoBoundingBoxFilter *GeoBoundingBoxFilter `json:"geo_bounding_box_filter"`
33
        Groups               []string              `json:"-"`
34
        TenantID             string                `json:"-"`
35
}
36

37
type AggregationTerm struct {
38
        Name         string            `json:"name"`
39
        Attribute    string            `json:"attribute"`
40
        Scope        string            `json:"scope"`
41
        Limit        int               `json:"limit"`
42
        Aggregations []AggregationTerm `json:"aggregations"`
43
}
44

45
func checkMaxNestedAggregationsWithLimit(value interface{}, limit uint) error {
14✔
46
        if limit <= 0 {
16✔
47
                return errors.Errorf("too many nested aggregations, limit is %d", maxNestedAggregations)
2✔
48
        }
2✔
49
        if aggs, ok := value.([]AggregationTerm); ok {
24✔
50
                for _, agg := range aggs {
24✔
51
                        if len(agg.Aggregations) > 0 {
22✔
52
                                return checkMaxNestedAggregationsWithLimit(agg.Aggregations, limit-1)
10✔
53
                        }
10✔
54
                }
55
        }
56
        return nil
2✔
57
}
58

59
func checkMaxNestedAggregations(value interface{}) error {
4✔
60
        return checkMaxNestedAggregationsWithLimit(value, maxNestedAggregations)
4✔
61
}
4✔
62

63
func (sp AggregateParams) Validate() error {
16✔
64
        err := validation.ValidateStruct(&sp,
16✔
65
                validation.Field(&sp.Aggregations, validation.Required,
16✔
66
                        validation.Length(1, maxAggregationTerms)))
16✔
67
        if err != nil {
24✔
68
                return err
8✔
69
        }
8✔
70

71
        for _, f := range sp.Filters {
13✔
72
                err := f.Validate()
5✔
73
                if err != nil {
7✔
74
                        return err
2✔
75
                }
2✔
76
        }
77
        return nil
6✔
78
}
79

80
func (f AggregationTerm) Validate() error {
18✔
81
        return validation.ValidateStruct(&f,
18✔
82
                validation.Field(&f.Name, validation.Required),
18✔
83
                validation.Field(&f.Attribute, validation.Required),
18✔
84
                validation.Field(&f.Scope, validation.Required),
18✔
85
                validation.Field(&f.Limit, validation.Min(0)),
18✔
86
                validation.Field(&f.Aggregations, validation.When(
18✔
87
                        len(f.Aggregations) > 0,
18✔
88
                        validation.Length(0, maxAggregationTerms),
18✔
89
                        validation.By(checkMaxNestedAggregations),
18✔
90
                )),
18✔
91
        )
18✔
92
}
18✔
93

94
type Aggregations map[string]interface{}
95

96
func BuildAggregations(terms []AggregationTerm) (*Aggregations, error) {
10✔
97
        aggs := Aggregations{}
10✔
98
        for _, term := range terms {
20✔
99
                terms := map[string]interface{}{
10✔
100
                        "field": ToAttr(term.Scope, term.Attribute, TypeStr),
10✔
101
                }
10✔
102
                limit := term.Limit
10✔
103
                if limit <= 0 {
16✔
104
                        limit = defaultAggregationLimit
6✔
105
                }
6✔
106
                terms["size"] = limit
10✔
107
                agg := map[string]interface{}{
10✔
108
                        "terms": terms,
10✔
109
                }
10✔
110
                if len(term.Aggregations) > 0 {
12✔
111
                        subaggs, err := BuildAggregations(term.Aggregations)
2✔
112
                        if err != nil {
2✔
UNCOV
113
                                return nil, err
×
UNCOV
114
                        }
×
115
                        agg["aggs"] = subaggs
2✔
116
                }
117
                aggs[term.Name] = agg
10✔
118
        }
119
        return &aggs, nil
10✔
120
}
121

122
type DeviceAggregation struct {
123
        Name       string                  `json:"name"`
124
        Items      []DeviceAggregationItem `json:"items"`
125
        OtherCount int                     `json:"other_count"`
126
}
127

128
type DeviceAggregationItem struct {
129
        Key          string              `json:"key"`
130
        Count        int                 `json:"count"`
131
        Aggregations []DeviceAggregation `json:"aggregations,omitempty"`
132
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc