entropychecker.WaitForEntropy   C
last analyzed

Complexity

Conditions 10

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 10.0296

Importance

Changes 0
Metric Value
cc 10
dl 0
loc 28
ccs 14
cts 15
cp 0.9333
crap 10.0296
rs 5.9999
c 0
b 0
f 0
eloc 22
nop 0

How to fix   Complexity   

Complexity

Complex classes like entropychecker.WaitForEntropy often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package entropychecker
2
3
import (
4
	"errors"
5
	"io/ioutil"
6
	"runtime"
7
	"strconv"
8
	"strings"
9
	"time"
10
)
11
12
// MinimumEntropy is the minimum amount of entropy that will be considered safe.
13
// Set this to what you consider to be a 'safe' minimum entropy amount (in bits)
14
var MinimumEntropy = 128
15
16
// Timeout sets the maximum amount of time to wait for entropy.
17
// Waiting for entropy will time out after this amount of time. Setting to zero will never time out.
18
var Timeout = time.Second * 10
19
20
// The only supported OS is linux at this time.
21
var supportedOS = "linux"
22
23
// ErrTimeout is for when the system waits too long and gives up
24
var ErrTimeout = errors.New("entropychecker: Timed out waiting for sufficient entropy")
25
26
// ErrUnsupportedOS is for for an invalid OS that does not provide entropy estimates
27
var ErrUnsupportedOS = errors.New("entropychecker: Unsupported OS. Only Linux is supported")
28
29
// GetEntropy gets the entropy estimate. Returns the estimated entropy in bits
30
func GetEntropy() (int, error) {
31 1
	if runtime.GOOS != supportedOS {
32 1
		return 0, ErrUnsupportedOS
33
	}
34
35 1
	text, err := ioutil.ReadFile("/proc/sys/kernel/random/entropy_avail")
36 1
	if err != nil {
37
		return 0, err
38
	}
39 1
	return strconv.Atoi(strings.TrimSuffix(string(text), "\n"))
40
}
41
42
// WaitForEntropy blocks until sufficient entropy is available
43
func WaitForEntropy() error {
44 1
	if runtime.GOOS != supportedOS {
45 1
		return ErrUnsupportedOS
46
	}
47
48
	// set up the timeout
49 1
	timeout := make(chan bool, 1)
50 1
	if Timeout != 0 {
51 1
		go func(timeoutDuration time.Duration) {
52 1
			time.Sleep(timeoutDuration)
53 1
			timeout <- true
54
		}(Timeout)
55
	}
56
57 1
	for {
58 1
		entropy, err := GetEntropy()
59
60 1
		switch {
61
		case err != nil:
62
			return err
63
		case entropy > MinimumEntropy:
64 1
			return nil
65
		default:
66 1
			select {
67
			case <-timeout:
68 1
				return ErrTimeout
69
			default:
70 1
				time.Sleep(50 * time.Millisecond)
71
			}
72
		}
73
	}
74
}
75