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

hyperledger / fabric-x-committer / 26441148829

26 May 2026 08:25AM UTC coverage: 91.367% (-0.04%) from 91.406%
26441148829

Pull #609

github

liran-funaro
[coordinator] Introduce a unified service manager

Signed-off-by: Liran Funaro <liran.funaro@gmail.com>
Pull Request #609: [coordinator] Introduce a unified service manager

308 of 325 new or added lines in 7 files covered. (94.77%)

15 existing lines in 9 files now uncovered.

10054 of 11004 relevant lines covered (91.37%)

42346.4 hits per line

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

80.33
/utils/utils.go
1
/*
2
Copyright IBM Corp. All Rights Reserved.
3

4
SPDX-License-Identifier: Apache-2.0
5
*/
6

7
package utils
8

9
import (
10
        "context"
11
        "crypto/rand"
12
        "encoding/json"
13
        "fmt"
14
        "io"
15
        "math/big"
16
        pseudorand "math/rand"
17
        "os"
18
        "strings"
19

20
        "github.com/cockroachdb/errors"
21
        "github.com/hyperledger/fabric-x-common/api/applicationpb"
22
        "github.com/hyperledger/fabric-x-common/api/committerpb"
23
        "google.golang.org/grpc/peer"
24
)
25

26
// ErrActiveStream represents the error when attempting to create a new stream while one is already active.
27
// The system only allows a single active stream at any given time.
28
var ErrActiveStream = errors.New("a stream is already active. Only one active stream is allowed at a time")
29

30
// FileExists returns true if a file path exists.
31
func FileExists(path string) bool {
8✔
32
        _, err := os.Stat(path)
8✔
33
        return !os.IsNotExist(err)
8✔
34
}
8✔
35

36
// LazyJSON will lazily marshal a struct for logging purposes.
37
type LazyJSON struct {
38
        O      any
39
        Indent string
40
}
41

42
// String marshals the give object as JSON.
43
func (lj *LazyJSON) String() string {
61✔
44
        if lj.O == nil {
61✔
45
                return "{}"
×
46
        }
×
47
        var p []byte
61✔
48
        var err error
61✔
49
        if lj.Indent != "" {
62✔
50
                p, err = json.MarshalIndent(lj.O, "", lj.Indent)
1✔
51
        } else {
61✔
52
                p, err = json.Marshal(lj.O)
60✔
53
        }
60✔
54
        if err != nil {
61✔
55
                return fmt.Sprintf("cannot marshal object: %v", err)
×
56
        }
×
57
        return string(p)
61✔
58
}
59

60
// Must panics given an error.
61
func Must(err error, msg ...string) {
7,329,545✔
62
        if err != nil {
7,329,545✔
63
                panic(errors.Wrap(err, strings.Join(msg, " ")))
×
64
        }
65
}
66

67
// Mustf panics given an error.
68
func Mustf(err error, format string, args ...any) {
16✔
69
        if err != nil {
16✔
70
                panic(errors.Wrapf(err, format, args...))
×
71
        }
72
}
73

74
// MustRead reads a byte array of the given size from the source.
75
// It panics if the read fails, or cannot read the requested size.
76
// "crypto/rand" and "math/rand" never fail and always returns the correct length.
77
func MustRead(source io.Reader, size int) []byte {
6,100,236✔
78
        value := make([]byte, size)
6,100,236✔
79
        n, err := source.Read(value)
6,100,236✔
80
        Must(err)
6,100,236✔
81
        if n != size {
6,100,236✔
82
                panic(errors.Errorf("expected size of %d, got %d", size, n))
×
83
        }
84
        return value
6,100,236✔
85
}
86

87
// ProcessErr wraps a non-nil error with a message using %w for unwrapping.
88
// Returns nil if the error is nil, otherwise returns the wrapped error.
89
// Example to the call of the function: utils.ProcessErr(g.Wait(), "sidecar has been stopped").
90
func ProcessErr(err error, msg string) error {
288✔
91
        if err != nil {
576✔
92
                return fmt.Errorf("%s: %w", msg, err) //nolint:wrapcheck
288✔
93
        }
288✔
UNCOV
94
        return nil
×
95
}
96

97
// CountAppearances returns the number of appearances each item have.
98
func CountAppearances[T comparable](items []T) map[T]int {
571✔
99
        countMap := make(map[T]int)
571✔
100
        for _, item := range items {
77,787✔
101
                countMap[item]++
77,216✔
102
        }
77,216✔
103
        return countMap
571✔
104
}
105

106
// ExtractServerAddress returns the stream's server (local) address.
107
func ExtractServerAddress(ctx context.Context) string {
546✔
108
        p, ok := peer.FromContext(ctx)
546✔
109
        if !ok || p == nil || p.LocalAddr == nil {
546✔
110
                return ""
×
111
        }
×
112
        return p.LocalAddr.String()
546✔
113
}
114

115
// IsConfigTx returns true if the namespaces indicate a config transaction.
116
func IsConfigTx(namespaces []*applicationpb.TxNamespace) bool {
31,497✔
117
        return len(namespaces) == 1 && namespaces[0].NsId == committerpb.ConfigNamespaceID
31,497✔
118
}
31,497✔
119

120
// RandIntN returns a true random (crypto/rand) number in the range [0, n).
121
// If it fails to read the crypto/rand stream, it falls back to a pseudo random number generator.
122
func RandIntN(n uint64) uint64 {
3,257✔
123
        // crypto/rand works with big.Int.
3,257✔
124
        var maxNumber big.Int
3,257✔
125
        maxNumber.SetUint64(n)
3,257✔
126
        res, _ := rand.Int(rand.Reader, &maxNumber)
3,257✔
127
        if res == nil {
3,257✔
128
                return uint64(pseudorand.Intn(int(n))) //nolint:gosec // fallback.
×
129
        }
×
130
        return res.Uint64()
3,257✔
131
}
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