Skip to content

Commit 9797a65

Browse files
authored
Merge pull request #5 from starius/minor-fixesx
cover errors.Is fix with tests
2 parents 417e254 + 8c35daa commit 9797a65

4 files changed

Lines changed: 94 additions & 5 deletions

File tree

loopd/daemon.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ var (
4747
errOnlyStartOnce = fmt.Errorf("daemon can only be started once")
4848
)
4949

50+
// shouldReportManagerErr determines whether a manager error should be forwarded
51+
// to the internal error channel. Context cancellations are treated as
52+
// non-fatal.
53+
func shouldReportManagerErr(err error) bool {
54+
return err != nil && !errors.Is(err, context.Canceled)
55+
}
56+
5057
// ListenerCfg holds closures used to retrieve listeners for the gRPC services.
5158
type ListenerCfg struct {
5259
// grpcListener returns a TLS listener to use for the gRPC server, based
@@ -892,7 +899,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
892899
defer infof("Static address manager stopped")
893900

894901
err := staticAddressManager.Run(d.mainCtx, initChan)
895-
if err != nil && !errors.Is(err, context.Canceled) {
902+
if shouldReportManagerErr(err) {
896903
d.internalErrChan <- err
897904
}
898905
}()
@@ -924,7 +931,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
924931
defer infof("Static address deposit manager stopped")
925932

926933
err := depositManager.Run(d.mainCtx, initChan)
927-
if err != nil && !errors.Is(err, context.Canceled) {
934+
if shouldReportManagerErr(err) {
928935
d.internalErrChan <- err
929936
}
930937
}()
@@ -956,7 +963,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
956963
defer infof("Static address withdrawal manager stopped")
957964

958965
err := withdrawalManager.Run(d.mainCtx, initChan)
959-
if err != nil && !errors.Is(err, context.Canceled) {
966+
if shouldReportManagerErr(err) {
960967
d.internalErrChan <- err
961968
}
962969
}()
@@ -992,7 +999,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error {
992999
infof("Starting static address loop-in manager...")
9931000
defer infof("Static address loop-in manager stopped")
9941001
err := staticLoopInManager.Run(d.mainCtx, initChan)
995-
if err != nil && !errors.Is(err, context.Canceled) {
1002+
if shouldReportManagerErr(err) {
9961003
d.internalErrChan <- err
9971004
}
9981005
}()

loopd/daemon_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package loopd
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// TestShouldReportManagerErr verifies that context cancellations are treated as
13+
// non-fatal while other errors are reported.
14+
func TestShouldReportManagerErr(t *testing.T) {
15+
t.Parallel()
16+
17+
tests := []struct {
18+
name string
19+
err error
20+
expected bool
21+
}{
22+
{
23+
name: "nil error",
24+
err: nil,
25+
expected: false,
26+
},
27+
{
28+
name: "context canceled",
29+
err: context.Canceled,
30+
expected: false,
31+
},
32+
{
33+
name: "wrapped context canceled",
34+
err: fmt.Errorf("wrap: %w", context.Canceled),
35+
expected: false,
36+
},
37+
{
38+
name: "other error",
39+
err: errors.New("boom"),
40+
expected: true,
41+
},
42+
}
43+
44+
for _, tt := range tests {
45+
tt := tt
46+
t.Run(tt.name, func(t *testing.T) {
47+
got := shouldReportManagerErr(tt.err)
48+
require.Equal(t, tt.expected, got)
49+
})
50+
}
51+
}

loopdb/store.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import (
1818
)
1919

2020
var (
21+
// bboltOpen allows overriding the open function in tests.
22+
bboltOpen = bbolt.Open
23+
2124
// dbFileName is the default file name of the client-side loop sub-swap
2225
// database.
2326
dbFileName = "loop.db"
@@ -191,7 +194,7 @@ func NewBoltSwapStore(dbPath string, chainParams *chaincfg.Params) (
191194
// Now that we know that path exists, we'll open up bolt, which
192195
// implements our default swap store.
193196
path := filepath.Join(dbPath, dbFileName)
194-
bdb, err := bbolt.Open(path, 0600, &bbolt.Options{
197+
bdb, err := bboltOpen(path, 0600, &bbolt.Options{
195198
Timeout: DefaultLoopDBTimeout,
196199
})
197200
if errors.Is(err, bbolt.ErrTimeout) {

loopdb/store_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package loopdb
33
import (
44
"context"
55
"crypto/sha256"
6+
"fmt"
67
"io/ioutil"
78
"os"
89
"path/filepath"
@@ -50,6 +51,33 @@ var (
5051
testTime = time.Date(2018, time.January, 9, 14, 00, 00, 0, time.UTC)
5152
)
5253

54+
// TestNewBoltSwapStoreTimeout ensures a wrapped bbolt timeout is detected
55+
// correctly when opening the store.
56+
func TestNewBoltSwapStoreTimeout(t *testing.T) {
57+
tempDir := t.TempDir()
58+
59+
// Override the bbolt open function to return a wrapped timeout.
60+
origOpen := bboltOpen
61+
t.Cleanup(func() {
62+
bboltOpen = origOpen
63+
})
64+
65+
wrappedErr := fmt.Errorf("wrapped: %w", bbolt.ErrTimeout)
66+
bboltOpen = func(path string, mode os.FileMode,
67+
options *bbolt.Options) (*bbolt.DB, error) {
68+
69+
require.NotNil(t, options)
70+
require.Equal(t, filepath.Join(tempDir, dbFileName), path)
71+
72+
return nil, wrappedErr
73+
}
74+
75+
store, err := NewBoltSwapStore(tempDir, &chaincfg.MainNetParams)
76+
require.Nil(t, store)
77+
require.ErrorIs(t, err, bbolt.ErrTimeout)
78+
require.ErrorContains(t, err, "couldn't obtain exclusive lock")
79+
}
80+
5381
// TestLoopOutStore tests all the basic functionality of the current bbolt
5482
// swap store.
5583
func TestLoopOutStore(t *testing.T) {

0 commit comments

Comments
 (0)