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

kubevirt / kubevirt / da26257f-8749-415a-b6b7-46330a8f66d0

09 May 2025 09:59AM UTC coverage: 71.469% (-0.1%) from 71.612%
da26257f-8749-415a-b6b7-46330a8f66d0

push

prow

web-flow
Merge pull request #13806 from iholder101/feature/expose-dirty-rate-stats-via-metric

Add dirty rate calculation via a `GetDomainDirtyRateStats()` gRPC method and a Promtehtus metric

45 of 248 new or added lines in 10 files covered. (18.15%)

33 existing lines in 7 files now uncovered.

62657 of 87670 relevant lines covered (71.47%)

0.8 hits per line

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

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

20
package patch
21

22
import (
23
        "encoding/json"
24
        "fmt"
25
        "strings"
26
)
27

28
type PatchOperation struct {
29
        Op    string      `json:"op"`
30
        Path  string      `json:"path"`
31
        Value interface{} `json:"value"`
32
}
33

34
const (
35
        PatchReplaceOp = "replace"
36
        PatchTestOp    = "test"
37
        PatchAddOp     = "add"
38
        PatchRemoveOp  = "remove"
39
)
40

41
func (p *PatchOperation) MarshalJSON() ([]byte, error) {
1✔
42
        switch p.Op {
1✔
43
        // The 'remove' operation is the only patching operation without a value
44
        // and it needs to be parsed differently.
45
        case PatchRemoveOp:
1✔
46
                return json.Marshal(&struct {
1✔
47
                        Op   string `json:"op"`
1✔
48
                        Path string `json:"path"`
1✔
49
                }{
1✔
50
                        Op:   p.Op,
1✔
51
                        Path: p.Path,
1✔
52
                })
1✔
53
        case PatchTestOp, PatchReplaceOp, PatchAddOp:
1✔
54
                return json.Marshal(&struct {
1✔
55
                        Op    string      `json:"op"`
1✔
56
                        Path  string      `json:"path"`
1✔
57
                        Value interface{} `json:"value"`
1✔
58
                }{
1✔
59
                        Op:    p.Op,
1✔
60
                        Path:  p.Path,
1✔
61
                        Value: p.Value,
1✔
62
                })
1✔
63
        default:
×
64
                return nil, fmt.Errorf("operation %s not recognized", p.Op)
×
65
        }
66
}
67

68
type PatchSet struct {
69
        patches []PatchOperation
70
}
71

72
type PatchOption func(patches *PatchSet)
73

74
func New(opts ...PatchOption) *PatchSet {
1✔
75
        p := &PatchSet{}
1✔
76
        p.AddOption(opts...)
1✔
77
        return p
1✔
78
}
1✔
79

80
func (p *PatchSet) GetPatches() []PatchOperation {
1✔
81
        return p.patches
1✔
82
}
1✔
83

84
func (p *PatchSet) AddOption(opts ...PatchOption) {
1✔
85
        for _, f := range opts {
2✔
86
                f(p)
1✔
87
        }
1✔
88
}
89

90
func (p *PatchSet) addOp(op, path string, value interface{}) {
1✔
91
        p.patches = append(p.patches, PatchOperation{
1✔
92
                Op:    op,
1✔
93
                Path:  path,
1✔
94
                Value: value,
1✔
95
        })
1✔
96
}
1✔
97

98
func WithTest(path string, value interface{}) PatchOption {
1✔
99
        return func(p *PatchSet) {
2✔
100
                p.addOp(PatchTestOp, path, value)
1✔
101
        }
1✔
102
}
103

104
func WithAdd(path string, value interface{}) PatchOption {
1✔
105
        return func(p *PatchSet) {
2✔
106
                p.addOp(PatchAddOp, path, value)
1✔
107
        }
1✔
108
}
109

110
func WithReplace(path string, value interface{}) PatchOption {
1✔
111
        return func(p *PatchSet) {
2✔
112
                p.addOp(PatchReplaceOp, path, value)
1✔
113
        }
1✔
114
}
115

116
func WithRemove(path string) PatchOption {
1✔
117
        return func(p *PatchSet) {
2✔
118
                p.addOp(PatchRemoveOp, path, nil)
1✔
119
        }
1✔
120
}
121

122
func (p *PatchSet) GeneratePayload() ([]byte, error) {
1✔
123
        return GeneratePatchPayload(p.patches...)
1✔
124
}
1✔
125

126
func (p *PatchSet) IsEmpty() bool {
1✔
127
        return len(p.patches) < 1
1✔
128
}
1✔
129

130
func (p *PatchSet) ToSlice() ([]string, error) {
1✔
131
        var result []string
1✔
132

1✔
133
        for _, operation := range p.patches {
2✔
134
                patch, err := operation.MarshalJSON()
1✔
135
                if err != nil {
1✔
UNCOV
136
                        return nil, err
×
137
                }
×
138

139
                result = append(result, string(patch))
1✔
140
        }
141

142
        return result, nil
1✔
143
}
144

145
func GeneratePatchPayload(patches ...PatchOperation) ([]byte, error) {
1✔
146
        if len(patches) == 0 {
1✔
UNCOV
147
                return nil, fmt.Errorf("list of patches is empty")
×
UNCOV
148
        }
×
149

150
        payloadBytes, err := json.Marshal(patches)
1✔
151
        if err != nil {
1✔
UNCOV
152
                return nil, err
×
UNCOV
153
        }
×
154

155
        return payloadBytes, nil
1✔
156
}
157

158
func GenerateTestReplacePatch(path string, oldValue, newValue interface{}) ([]byte, error) {
1✔
159
        return GeneratePatchPayload(
1✔
160
                PatchOperation{
1✔
161
                        Op:    PatchTestOp,
1✔
162
                        Path:  path,
1✔
163
                        Value: oldValue,
1✔
164
                },
1✔
165
                PatchOperation{
1✔
166
                        Op:    PatchReplaceOp,
1✔
167
                        Path:  path,
1✔
168
                        Value: newValue,
1✔
169
                },
1✔
170
        )
1✔
171
}
1✔
172

173
func UnmarshalPatch(patch []byte) ([]PatchOperation, error) {
1✔
174
        var p []PatchOperation
1✔
175
        err := json.Unmarshal(patch, &p)
1✔
176

1✔
177
        return p, err
1✔
178
}
1✔
179

180
func EscapeJSONPointer(ptr string) string {
1✔
181
        s := strings.ReplaceAll(ptr, "~", "~0")
1✔
182
        return strings.ReplaceAll(s, "/", "~1")
1✔
183
}
1✔
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

© 2026 Coveralls, Inc