PageRenderTime 918ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/test/integration/utils.go

https://bitbucket.org/acaisoft/fabric-sdk-go
Go | 207 lines | 145 code | 33 blank | 29 comment | 41 complexity | 6b2a5965aca703a308e6000eec8a2ba4 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. Copyright SecureKey Technologies Inc. All Rights Reserved.
  3. SPDX-License-Identifier: Apache-2.0
  4. */
  5. package integration
  6. import (
  7. "math/rand"
  8. "os"
  9. "testing"
  10. "fmt"
  11. "strings"
  12. "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
  13. "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
  14. "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
  15. fabApi "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
  16. "github.com/hyperledger/fabric-sdk-go/pkg/core/config/lookup"
  17. "github.com/hyperledger/fabric-sdk-go/pkg/core/cryptosuite"
  18. "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
  19. "github.com/hyperledger/fabric-sdk-go/pkg/msp"
  20. "github.com/pkg/errors"
  21. )
  22. const (
  23. adminUser = "Admin"
  24. ordererOrgName = "ordererorg"
  25. )
  26. // GenerateRandomID generates random ID
  27. func GenerateRandomID() string {
  28. return randomString(10)
  29. }
  30. // Utility to create random string of strlen length
  31. func randomString(strlen int) string {
  32. const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
  33. result := make([]byte, strlen)
  34. for i := 0; i < strlen; i++ {
  35. result[i] = chars[rand.Intn(len(chars))]
  36. }
  37. return string(result)
  38. }
  39. // InitializeChannel ...
  40. func InitializeChannel(sdk *fabsdk.FabricSDK, orgID string, req resmgmt.SaveChannelRequest, targets []string) error {
  41. joinedTargets, err := FilterTargetsJoinedChannel(sdk, orgID, req.ChannelID, targets)
  42. if err != nil {
  43. return errors.WithMessage(err, "checking for joined targets failed")
  44. }
  45. if len(joinedTargets) != len(targets) {
  46. _, err := CreateChannel(sdk, req)
  47. if err != nil {
  48. return errors.Wrapf(err, "create channel failed")
  49. }
  50. _, err = JoinChannel(sdk, req.ChannelID, orgID)
  51. if err != nil {
  52. return errors.Wrapf(err, "join channel failed")
  53. }
  54. }
  55. return nil
  56. }
  57. // FilterTargetsJoinedChannel filters targets to those that have joined the named channel.
  58. func FilterTargetsJoinedChannel(sdk *fabsdk.FabricSDK, orgID string, channelID string, targets []string) ([]string, error) {
  59. var joinedTargets []string
  60. //prepare context
  61. clientContext := sdk.Context(fabsdk.WithUser(adminUser), fabsdk.WithOrg(orgID))
  62. rc, err := resmgmt.New(clientContext)
  63. if err != nil {
  64. return nil, errors.WithMessage(err, "failed getting admin user session for org")
  65. }
  66. for _, target := range targets {
  67. // Check if primary peer has joined channel
  68. alreadyJoined, err := HasPeerJoinedChannel(rc, target, channelID)
  69. if err != nil {
  70. return nil, errors.WithMessage(err, "failed while checking if primary peer has already joined channel")
  71. }
  72. if alreadyJoined {
  73. joinedTargets = append(joinedTargets, target)
  74. }
  75. }
  76. return joinedTargets, nil
  77. }
  78. // CreateChannel attempts to save the named channel.
  79. func CreateChannel(sdk *fabsdk.FabricSDK, req resmgmt.SaveChannelRequest) (bool, error) {
  80. //prepare context
  81. clientContext := sdk.Context(fabsdk.WithUser(adminUser), fabsdk.WithOrg(ordererOrgName))
  82. // Channel management client is responsible for managing channels (create/update)
  83. resMgmtClient, err := resmgmt.New(clientContext)
  84. if err != nil {
  85. return false, errors.WithMessage(err, "Failed to create new channel management client")
  86. }
  87. // Create channel (or update if it already exists)
  88. if _, err = resMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts)); err != nil {
  89. return false, err
  90. }
  91. return true, nil
  92. }
  93. // JoinChannel attempts to save the named channel.
  94. func JoinChannel(sdk *fabsdk.FabricSDK, name, orgID string) (bool, error) {
  95. //prepare context
  96. clientContext := sdk.Context(fabsdk.WithUser(adminUser), fabsdk.WithOrg(orgID))
  97. // Resource management client is responsible for managing resources (joining channels, install/instantiate/upgrade chaincodes)
  98. resMgmtClient, err := resmgmt.New(clientContext)
  99. if err != nil {
  100. return false, errors.WithMessage(err, "Failed to create new resource management client")
  101. }
  102. if err = resMgmtClient.JoinChannel(name, resmgmt.WithRetry(retry.DefaultResMgmtOpts)); err != nil {
  103. return false, nil
  104. }
  105. return true, nil
  106. }
  107. // OrgTargetPeers determines peer endpoints for orgs
  108. func OrgTargetPeers(orgs []string, configBackend ...core.ConfigBackend) ([]string, error) {
  109. networkConfig := fabApi.NetworkConfig{}
  110. err := lookup.New(configBackend...).UnmarshalKey("organizations", &networkConfig.Organizations)
  111. if err != nil {
  112. return nil, errors.WithMessage(err, "failed to get organizations from config ")
  113. }
  114. var peers []string
  115. for _, org := range orgs {
  116. orgConfig, ok := networkConfig.Organizations[strings.ToLower(org)]
  117. if !ok {
  118. continue
  119. }
  120. peers = append(peers, orgConfig.Peers...)
  121. }
  122. return peers, nil
  123. }
  124. // HasPeerJoinedChannel checks whether the peer has already joined the channel.
  125. // It returns true if it has, false otherwise, or an error
  126. func HasPeerJoinedChannel(client *resmgmt.Client, target string, channel string) (bool, error) {
  127. foundChannel := false
  128. response, err := client.QueryChannels(resmgmt.WithTargetEndpoints(target), resmgmt.WithRetry(retry.DefaultResMgmtOpts))
  129. if err != nil {
  130. return false, errors.WithMessage(err, "failed to query channel for peer")
  131. }
  132. for _, responseChannel := range response.Channels {
  133. if responseChannel.ChannelId == channel {
  134. foundChannel = true
  135. }
  136. }
  137. return foundChannel, nil
  138. }
  139. // CleanupTestPath removes the contents of a state store.
  140. func CleanupTestPath(t *testing.T, storePath string) {
  141. err := os.RemoveAll(storePath)
  142. if err != nil {
  143. if t == nil {
  144. panic(fmt.Sprintf("Cleaning up directory '%s' failed: %v", storePath, err))
  145. }
  146. t.Fatalf("Cleaning up directory '%s' failed: %v", storePath, err)
  147. }
  148. }
  149. // CleanupUserData removes user data.
  150. func CleanupUserData(t *testing.T, sdk *fabsdk.FabricSDK) {
  151. var keyStorePath, credentialStorePath string
  152. configBackend, err := sdk.Config()
  153. if err != nil {
  154. // if an error is returned from Config, it means configBackend was nil, in this case simply hard code
  155. // the keyStorePath and credentialStorePath to the default values
  156. // This case is mostly happening due to configless test that is not passing a ConfigProvider to the SDK
  157. // which makes configBackend = nil.
  158. // Since configless test uses the same config values as the default ones (config_test.yaml), it's safe to
  159. // hard code these paths here
  160. keyStorePath = "/tmp/msp/keystore"
  161. credentialStorePath = "/tmp/state-store"
  162. } else {
  163. cryptoSuiteConfig := cryptosuite.ConfigFromBackend(configBackend)
  164. identityConfig, err := msp.ConfigFromBackend(configBackend)
  165. if err != nil {
  166. t.Fatal(err)
  167. }
  168. keyStorePath = cryptoSuiteConfig.KeyStorePath()
  169. credentialStorePath = identityConfig.CredentialStorePath()
  170. }
  171. CleanupTestPath(t, keyStorePath)
  172. CleanupTestPath(t, credentialStorePath)
  173. }