Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 2061a93

Browse files
committed
[FAB-8944] Add more unit tests for channel config cache
Change-Id: Ic1263079e95793407cd1ac2ebc7d0540a26856c4 Signed-off-by: Divyank Katira <Divyank.Katira@securekey.com>
1 parent 38d16da commit 2061a93

File tree

9 files changed

+275
-24
lines changed

9 files changed

+275
-24
lines changed

pkg/fab/channel/membership/cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func NewRefCache(refresh time.Duration) *lazycache.Cache {
5151
initializer := func(key lazycache.Key) (interface{}, error) {
5252
ck, ok := key.(CacheKey)
5353
if !ok {
54-
return nil, errors.New("Unexpected cache key")
54+
return nil, errors.New("unexpected cache key")
5555
}
5656
return NewRef(refresh, ck.Context(), ck.ChConfigRef()), nil
5757
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
Copyright SecureKey Technologies Inc. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package membership
8+
9+
import (
10+
"fmt"
11+
"testing"
12+
"time"
13+
14+
"github.com/golang/protobuf/proto"
15+
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
16+
"github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
17+
"github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazyref"
18+
mb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/msp"
19+
"github.com/stretchr/testify/assert"
20+
)
21+
22+
type badKey struct {
23+
s string
24+
}
25+
26+
func (b *badKey) String() string {
27+
return b.s
28+
}
29+
30+
func TestMembershipCache(t *testing.T) {
31+
testChannelID := "test"
32+
goodMSPID := "GoodMSP"
33+
34+
cfg := mocks.NewMockChannelCfg(testChannelID)
35+
cfg.MockMSPs = []*mb.MSPConfig{buildMSPConfig(goodMSPID, []byte(validRootCA))}
36+
37+
ctx := mocks.NewMockProviderContext()
38+
39+
cache := NewRefCache(time.Millisecond * 10)
40+
assert.NotNil(t, cache)
41+
42+
key, err := NewCacheKey(Context{ctx}, lazyref.New(func() (interface{}, error) { return cfg, nil }), testChannelID)
43+
assert.Nil(t, err)
44+
assert.NotNil(t, key)
45+
46+
ch := key.ChannelID()
47+
assert.Equal(t, testChannelID, ch)
48+
49+
r, err := cache.Get(key)
50+
assert.Nil(t, err)
51+
assert.NotNil(t, r)
52+
53+
mem, ok := r.(fab.ChannelMembership)
54+
assert.True(t, ok)
55+
56+
sID := &mb.SerializedIdentity{Mspid: goodMSPID, IdBytes: []byte(certPem)}
57+
goodEndorser, err := proto.Marshal(sID)
58+
assert.Nil(t, err)
59+
60+
err = mem.Validate(goodEndorser)
61+
assert.Nil(t, err)
62+
63+
err = mem.Verify(goodEndorser, []byte("test"), []byte("test1"))
64+
assert.Nil(t, err)
65+
}
66+
67+
func TestMembershipCacheBad(t *testing.T) {
68+
testChannelID := "test"
69+
testErr := fmt.Errorf("bad initializer")
70+
71+
ctx := mocks.NewMockProviderContext()
72+
73+
cache := NewRefCache(time.Millisecond * 10)
74+
assert.NotNil(t, cache)
75+
76+
r, err := cache.Get(&badKey{s: "test"})
77+
assert.NotNil(t, err)
78+
assert.Equal(t, "unexpected cache key", err.Error())
79+
assert.Nil(t, r)
80+
81+
key, err := NewCacheKey(Context{ctx}, lazyref.New(func() (interface{}, error) { return nil, testErr }), testChannelID)
82+
assert.Nil(t, err)
83+
assert.NotNil(t, key)
84+
85+
r, err = cache.Get(key)
86+
assert.Nil(t, err)
87+
assert.NotNil(t, r)
88+
89+
mem, ok := r.(fab.ChannelMembership)
90+
assert.True(t, ok)
91+
92+
err = mem.Validate([]byte("MSP"))
93+
assert.NotNil(t, err)
94+
assert.Contains(t, err.Error(), testErr.Error())
95+
96+
err = mem.Verify([]byte("MSP"), []byte("test"), []byte("test1"))
97+
assert.NotNil(t, err)
98+
assert.Contains(t, err.Error(), testErr.Error())
99+
}

pkg/fab/chconfig/cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func NewRefCache(refresh time.Duration) *lazycache.Cache {
6060
initializer := func(key lazycache.Key) (interface{}, error) {
6161
ck, ok := key.(CacheKey)
6262
if !ok {
63-
return nil, errors.New("Unexpected cache key")
63+
return nil, errors.New("unexpected cache key")
6464
}
6565
return NewRef(refresh, ck.Provider(), ck.ChannelID(), ck.Context()), nil
6666
}

pkg/fab/chconfig/cache_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright SecureKey Technologies Inc. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package chconfig
8+
9+
import (
10+
"fmt"
11+
"testing"
12+
"time"
13+
14+
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
15+
"github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
16+
"github.com/stretchr/testify/assert"
17+
18+
mspmocks "github.com/hyperledger/fabric-sdk-go/pkg/msp/test/mockmsp"
19+
)
20+
21+
const (
22+
badProviderErrMessage = "bad provider"
23+
)
24+
25+
func TestChannelConfigCache(t *testing.T) {
26+
user := mspmocks.NewMockSigningIdentity("user", "user")
27+
clientCtx := mocks.NewMockContext(user)
28+
29+
cache := NewRefCache(time.Millisecond * 10)
30+
assert.NotNil(t, cache)
31+
32+
key, err := NewCacheKey(clientCtx, mockProvider, "test")
33+
assert.Nil(t, err)
34+
assert.NotNil(t, key)
35+
36+
r, err := cache.Get(key)
37+
assert.Nil(t, err)
38+
assert.NotNil(t, r)
39+
}
40+
41+
func TestChannelConfigCacheBad(t *testing.T) {
42+
user := mspmocks.NewMockSigningIdentity("user", "user")
43+
clientCtx := mocks.NewMockContext(user)
44+
45+
cache := NewRefCache(time.Millisecond * 10)
46+
assert.NotNil(t, cache)
47+
48+
r, err := cache.Get(&badKey{s: "test"})
49+
assert.NotNil(t, err)
50+
assert.Equal(t, "unexpected cache key", err.Error())
51+
assert.Nil(t, r)
52+
53+
key, err := NewCacheKey(clientCtx, badProvider, "test")
54+
assert.Nil(t, err)
55+
assert.NotNil(t, key)
56+
57+
cache = NewRefCache(time.Millisecond * 10)
58+
assert.NotNil(t, cache)
59+
60+
r, err = cache.Get(key)
61+
assert.NotNil(t, r)
62+
assert.Nil(t, err)
63+
64+
c, err := r.(*Ref).Get()
65+
assert.NotNil(t, err)
66+
assert.Nil(t, c)
67+
assert.Contains(t, err.Error(), badProviderErrMessage)
68+
}
69+
70+
type badKey struct {
71+
s string
72+
}
73+
74+
func (b *badKey) String() string {
75+
return b.s
76+
}
77+
78+
func mockProvider(channelID string) (fab.ChannelConfig, error) {
79+
return mocks.NewMockChannelConfig(nil, channelID)
80+
}
81+
82+
func badProvider(channelID string) (fab.ChannelConfig, error) {
83+
return nil, fmt.Errorf(badProviderErrMessage)
84+
}

pkg/fabsdk/fabsdk_chconfig_test.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ import (
1818
)
1919

2020
const (
21-
sdkValidClientOrg2 = "Org2"
21+
sdkValidClientOrg2 = "org2"
2222
)
2323

24-
// TODO: (divyank) Re-enable.
25-
func testNewDefaultSDK(t *testing.T) {
24+
func TestNewDefaultSDK(t *testing.T) {
2625
// Test New SDK with valid config file
2726
sdk, err := New(configImpl.FromFile(sdkConfigFile))
2827
if err != nil {
@@ -48,8 +47,7 @@ func verifySDK(t *testing.T, sdk *FabricSDK) {
4847
}
4948
}
5049

51-
// TODO: (divyank) Re-enable.
52-
func testWithConfigOpt(t *testing.T) {
50+
func TestWithConfigOpt(t *testing.T) {
5351
// Test New SDK with valid config file
5452
c, err := configImpl.FromFile(sdkConfigFile)()
5553
if err != nil {
@@ -64,8 +62,7 @@ func testWithConfigOpt(t *testing.T) {
6462
verifySDK(t, sdk)
6563
}
6664

67-
// TODO: (divyank) Re-enable.
68-
func testNewDefaultTwoValidSDK(t *testing.T) {
65+
func TestNewDefaultTwoValidSDK(t *testing.T) {
6966
sdk1, err := New(configImpl.FromFile(sdkConfigFile))
7067
if err != nil {
7168
t.Fatalf("Error initializing SDK: %s", err)
@@ -100,7 +97,7 @@ func testNewDefaultTwoValidSDK(t *testing.T) {
10097
}
10198

10299
if client2.Organization != sdkValidClientOrg2 {
103-
t.Fatalf("Unexpected org in config: %s", client1.Organization)
100+
t.Fatalf("Unexpected org in config: %s", client2.Organization)
104101
}
105102

106103
// Get a common client context for the following tests

pkg/fabsdk/provider/chpvdr/chprovider.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ func (cp *ChannelProvider) ChannelService(ctx fab.ClientContext, channelID strin
3939

4040
// ChannelService provides Channel clients and maintains contexts for them.
4141
// the identity context is used
42-
//
43-
// TODO: add cache for channel rather than reconstructing each time.
4442
type ChannelService struct {
4543
provider *ChannelProvider
4644
infraProvider fab.InfraProvider
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// +build testing
2+
3+
/*
4+
Copyright SecureKey Technologies Inc. All Rights Reserved.
5+
6+
SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
package fabpvdr
10+
11+
import (
12+
"testing"
13+
14+
"github.com/hyperledger/fabric-sdk-go/pkg/fab/chconfig"
15+
"github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
16+
"github.com/stretchr/testify/assert"
17+
18+
mspmocks "github.com/hyperledger/fabric-sdk-go/pkg/msp/test/mockmsp"
19+
)
20+
21+
func TestCreateChannelCfg(t *testing.T) {
22+
p := newInfraProvider(t)
23+
testChannelID := "test"
24+
p.chCfgCache = newMockChCfgCache(chconfig.NewChannelCfg(testChannelID))
25+
ctx := mocks.NewMockProviderContext()
26+
user := mspmocks.NewMockSigningIdentity("user", "user")
27+
clientCtx := &mockClientContext{
28+
Providers: ctx,
29+
SigningIdentity: user,
30+
}
31+
32+
m, err := p.CreateChannelCfg(clientCtx, "")
33+
assert.Nil(t, err)
34+
assert.NotNil(t, m)
35+
36+
m, err = p.CreateChannelCfg(clientCtx, testChannelID)
37+
assert.Nil(t, err)
38+
assert.NotNil(t, m)
39+
40+
p.Close()
41+
}

pkg/fabsdk/provider/fabpvdr/fabprovider_testing_env.go

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,57 @@ SPDX-License-Identifier: Apache-2.0
99
package fabpvdr
1010

1111
import (
12+
"sync"
13+
1214
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
15+
"github.com/hyperledger/fabric-sdk-go/pkg/fab/chconfig"
1316
"github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazycache"
17+
"github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazyref"
18+
"github.com/pkg/errors"
1419
)
1520

1621
// SetChannelConfig allows setting channel configuration.
1722
// This method is intended to enable tests and should not be called.
1823
func (f *InfraProvider) SetChannelConfig(cfg fab.ChannelCfg) {
19-
f.chCfgCache = newMockCache(cfg)
24+
if _, ok := f.chCfgCache.(*chCfgCache); !ok {
25+
f.chCfgCache = newMockChCfgCache(cfg)
26+
} else {
27+
f.chCfgCache.(*chCfgCache).Put(cfg)
28+
}
29+
}
30+
31+
type chCfgCache struct {
32+
cfgMap sync.Map
2033
}
2134

22-
type mockCache struct {
23-
cfg fab.ChannelCfg
35+
func newMockChCfgCache(cfg fab.ChannelCfg) cache {
36+
c := &chCfgCache{}
37+
c.cfgMap.Store(cfg.ID(), newChCfgRef(cfg))
38+
return c
2439
}
2540

26-
func newMockCache(cfg fab.ChannelCfg) cache {
27-
return &mockCache{cfg: cfg}
41+
func newChCfgRef(cfg fab.ChannelCfg) *chconfig.Ref {
42+
r := &chconfig.Ref{}
43+
r.Reference = lazyref.New(func() (interface{}, error) {
44+
return cfg, nil
45+
})
46+
return r
2847
}
2948

30-
func (m *mockCache) Get(lazycache.Key) (interface{}, error) {
31-
return m.cfg, nil
49+
// Get mock channel config reference
50+
func (m *chCfgCache) Get(k lazycache.Key) (interface{}, error) {
51+
cfg, ok := m.cfgMap.Load(k.(chconfig.CacheKey).ChannelID())
52+
if !ok {
53+
return nil, errors.New("Channel config not found in cache")
54+
}
55+
return cfg, nil
3256
}
33-
func (m *mockCache) Close() {
57+
58+
// Close not implemented
59+
func (m *chCfgCache) Close() {
60+
}
61+
62+
// Put channel config reference into mock cache
63+
func (m *chCfgCache) Put(cfg fab.ChannelCfg) {
64+
m.cfgMap.Store(cfg.ID(), newChCfgRef(cfg))
3465
}

0 commit comments

Comments
 (0)