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

NVIDIA / gpu-operator / 29513807383

16 Jul 2026 03:58PM UTC coverage: 32.688% (+0.9%) from 31.812%
29513807383

Pull #2571

github

karthikvetrivel
Add golden render tests for GPUCluster operand manifests

Signed-off-by: Karthik Vetrivel <kvetrivel@nvidia.com>
Pull Request #2571: Add GPUCluster CRD and controller for DRA-based stack

513 of 1343 new or added lines in 31 files covered. (38.2%)

5 existing lines in 4 files now uncovered.

4663 of 14265 relevant lines covered (32.69%)

0.37 hits per line

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

40.24
/internal/utils/utils.go
1
/**
2
# Copyright (c) NVIDIA CORPORATION.  All rights reserved.
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

17
package utils
18

19
import (
20
        "fmt"
21
        "hash"
22
        "hash/fnv"
23
        "os"
24
        "path/filepath"
25
        "reflect"
26
        "slices"
27
        "sort"
28
        "strings"
29

30
        "github.com/davecgh/go-spew/spew"
31
        "k8s.io/apimachinery/pkg/util/rand"
32
)
33

34
// GetFilesWithSuffix returns all files under a given base directory that have a specific suffix
35
// The operation is performed recursively on subdirectories as well
36
func GetFilesWithSuffix(baseDir string, suffixes ...string) ([]string, error) {
×
37
        var files []string
×
38
        err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error {
×
39
                // Error during traversal
×
40
                if err != nil {
×
41
                        return err
×
42
                }
×
43

44
                if info.IsDir() {
×
45
                        return nil
×
46
                }
×
47

48
                // Skip non suffix files
49
                base := info.Name()
×
50
                for _, s := range suffixes {
×
51
                        if strings.HasSuffix(base, s) {
×
52
                                files = append(files, path)
×
53
                        }
×
54
                }
55
                return nil
×
56
        })
57

58
        if err != nil {
×
59
                return nil, fmt.Errorf("error traversing directory tree: %w", err)
×
60
        }
×
61
        return files, nil
×
62
}
63

64
var spewPrinter = spew.ConfigState{
65
        Indent:         " ",
66
        SortKeys:       true,
67
        DisableMethods: true,
68
        SpewKeys:       true,
69
}
70

71
// GetObjectHash returns an FNV-32a hash of the full object (all fields).
72
func GetObjectHash(obj interface{}) string {
1✔
73
        hasher := fnv.New32a()
1✔
74
        spewPrinter.Fprintf(hasher, "%#v", obj)
1✔
75
        return fmt.Sprint(hasher.Sum32())
1✔
76
}
1✔
77

78
// GetObjectHashIgnoreEmptyKeys returns an FNV-32a hash of only the non-zero
79
// fields of a struct. Adding a new zero-valued field will not change
80
// the digest. Embedded structs are flattened.
81
func GetObjectHashIgnoreEmptyKeys(obj interface{}) string {
1✔
82
        hasher := fnv.New32a()
1✔
83
        hashNonZeroFields(hasher, reflect.Indirect(reflect.ValueOf(obj)))
1✔
84
        return fmt.Sprint(hasher.Sum32())
1✔
85
}
1✔
86

87
// isEffectivelyZero returns true if a field is zero-valued or is an empty
88
// slice/map. reflect.IsZero treats nil slices as zero but non-nil empty
89
// slices ([]T{}) as non-zero; we treat both as zero so that the digest
90
// is not affected by the distinction.
91
func isEffectivelyZero(fv reflect.Value) bool {
1✔
92
        if fv.IsZero() {
2✔
93
                return true
1✔
94
        }
1✔
95
        k := fv.Kind()
1✔
96
        return (k == reflect.Slice || k == reflect.Map) && fv.Len() == 0
1✔
97
}
98

99
// hashNonZeroFields hashes non-zero struct fields in alphabetical order by
100
// field name, so the digest is independent of field declaration order.
101
// Embedded (anonymous) structs are flattened into the same sorted pool.
102
func hashNonZeroFields(h hash.Hash32, v reflect.Value) {
1✔
103
        fields := reflect.VisibleFields(v.Type())
1✔
104
        sort.Slice(fields, func(a, b int) bool {
2✔
105
                return fields[a].Name < fields[b].Name
1✔
106
        })
1✔
107
        for _, f := range fields {
2✔
108
                if f.Anonymous {
2✔
109
                        continue
1✔
110
                }
111
                fv := v.FieldByIndex(f.Index)
1✔
112
                if !isEffectivelyZero(fv) {
2✔
113
                        fmt.Fprintf(h, "%s:", f.Name)
1✔
114
                        spewPrinter.Fprintf(h, "%#v", fv.Interface())
1✔
115
                }
1✔
116
        }
117
}
118

119
func GetStringHash(s string) string {
1✔
120
        hasher := fnv.New32a()
1✔
121
        if _, err := hasher.Write([]byte(s)); err != nil {
1✔
122
                panic(err)
×
123
        }
124
        return rand.SafeEncodeString(fmt.Sprint(hasher.Sum32()))
1✔
125
}
126

127
// PrependPathListEnvvar prepends a specified list of strings to a specified envvar and returns its value.
NEW
128
func PrependPathListEnvvar(envvar string, prepend ...string) string {
×
NEW
129
        if len(prepend) == 0 {
×
NEW
130
                return os.Getenv(envvar)
×
NEW
131
        }
×
NEW
132
        current := filepath.SplitList(os.Getenv(envvar))
×
NEW
133
        return strings.Join(append(prepend, current...), string(filepath.ListSeparator))
×
134
}
135

136
// SetEnvVar adds or updates an envvar in the list of specified envvars and returns it.
NEW
137
func SetEnvVar(envvars []string, key, value string) []string {
×
NEW
138
        envvars = slices.DeleteFunc(envvars, func(e string) bool {
×
NEW
139
                return strings.HasPrefix(e, key+"=")
×
NEW
140
        })
×
NEW
141
        return append(envvars, key+"="+value)
×
142
}
143

144
// WriteFileAtomically writes content to the specified file via a temp file + rename,
145
// so readers never observe a partially written file.
NEW
146
func WriteFileAtomically(path, content string) error {
×
NEW
147
        tmpFile, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)+".*.tmp")
×
NEW
148
        if err != nil {
×
NEW
149
                return fmt.Errorf("failed to create temporary file: %w", err)
×
NEW
150
        }
×
151
        // Best-effort cleanup; on success the rename moves the temp file away first.
NEW
152
        defer func() { _ = os.Remove(tmpFile.Name()) }() //nolint:gosec
×
153

NEW
154
        if _, err := tmpFile.WriteString(content); err != nil {
×
NEW
155
                tmpFile.Close()
×
NEW
156
                return fmt.Errorf("failed to write temporary file: %w", err)
×
NEW
157
        }
×
NEW
158
        if err := tmpFile.Close(); err != nil {
×
NEW
159
                return fmt.Errorf("failed to close temporary file: %w", err)
×
NEW
160
        }
×
NEW
161
        if err := os.Rename(tmpFile.Name(), path); err != nil {
×
NEW
162
                return fmt.Errorf("error moving temporary file to %q: %w", path, err)
×
NEW
163
        }
×
NEW
164
        return nil
×
165
}
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