github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/ledger/reset_rollback_test.go (about) 1 /* 2 Copyright hechain All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package ledger 8 9 import ( 10 "encoding/base64" 11 "encoding/json" 12 "fmt" 13 "io/ioutil" 14 "os" 15 "path/filepath" 16 "strings" 17 "syscall" 18 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 22 docker "github.com/fsouza/go-dockerclient" 23 "github.com/hechain20/hechain/integration/nwo" 24 "github.com/hechain20/hechain/integration/nwo/commands" 25 "github.com/hyperledger/fabric-protos-go/common" 26 "github.com/onsi/gomega/gbytes" 27 "github.com/onsi/gomega/gexec" 28 "github.com/tedsuo/ifrit" 29 ) 30 31 var _ = Describe("rollback, reset, pause, resume, and unjoin peer node commands", func() { 32 // at the beginning of each test under this block, we have defined two collections: 33 // 1. collectionMarbles - Org1 and Org2 have access to this collection 34 // 2. collectionMarblePrivateDetails - Org2 and Org3 have access to this collection 35 // when calling QueryChaincode with first arg "readMarble", it will query collectionMarbles[1] 36 // when calling QueryChaincode with first arg "readMarblePrivateDetails", it will query collectionMarblePrivateDetails[2] 37 var ( 38 setup *setup 39 helper *testHelper 40 ) 41 42 BeforeEach(func() { 43 setup = initThreeOrgsSetup() 44 nwo.EnableCapabilities(setup.network, setup.channelID, "Application", "V2_0", setup.orderer, setup.peers...) 45 helper = &testHelper{ 46 networkHelper: &networkHelper{ 47 Network: setup.network, 48 orderer: setup.orderer, 49 peers: setup.peers, 50 testDir: setup.testDir, 51 channelID: setup.channelID, 52 }, 53 } 54 55 By("installing and instantiating chaincode on all peers") 56 chaincode := nwo.Chaincode{ 57 Name: "marblesp", 58 Version: "1.0", 59 Path: components.Build("github.com/hechain20/hechain/integration/chaincode/marbles_private/cmd"), 60 Lang: "binary", 61 PackageFile: filepath.Join(setup.testDir, "marbles-pvtdata.tar.gz"), 62 Label: "marbles-private-20", 63 SignaturePolicy: `OR ('Org1MSP.member','Org2MSP.member', 'Org3MSP.member')`, 64 CollectionsConfig: filepath.Join("testdata", "collection_configs", "collections_config1.json"), 65 Sequence: "1", 66 } 67 68 helper.deployChaincode(chaincode) 69 70 org2peer0 := setup.network.Peer("Org2", "peer0") 71 height := helper.getLedgerHeight(org2peer0) 72 73 By("creating 5 blocks") 74 for i := 1; i <= 5; i++ { 75 helper.addMarble("marblesp", fmt.Sprintf(`{"name":"marble%d", "color":"blue", "size":35, "owner":"tom", "price":99}`, i), org2peer0) 76 helper.waitUntilAllPeersEqualLedgerHeight(height + i) 77 } 78 79 By("verifying marble1 to marble5 exist in collectionMarbles & collectionMarblePrivateDetails in Org2.peer0") 80 for i := 1; i <= 5; i++ { 81 helper.assertPresentInCollectionM("marblesp", fmt.Sprintf("marble%d", i), org2peer0) 82 helper.assertPresentInCollectionMPD("marblesp", fmt.Sprintf("marble%d", i), org2peer0) 83 } 84 }) 85 86 AfterEach(func() { 87 setup.cleanup() 88 }) 89 90 // This test executes the rollback, reset, pause, and resume commands on the following peerss 91 // Org1.peer0 - rollback 92 // Org2.peer0 - reset 93 // Org3.peer0 - pause/rollback/resume 94 // 95 // There are 14 blocks created in BeforeEach (before rollback/reset). 96 // block 0: genesis, block 1: org1Anchor, block 2: org2Anchor, block 3: org3Anchor 97 // block 4 to 8: chaincode instantiation, block 9 to 13: chaincode invoke to add marbles. 98 It("pauses and resumes channels and rolls back and resets the ledger", func() { 99 By("Checking ledger height on each peer") 100 for _, peer := range helper.peers { 101 Expect(helper.getLedgerHeight(peer)).Should(Equal(14)) 102 } 103 104 org1peer0 := setup.network.Peer("Org1", "peer0") 105 org2peer0 := setup.network.Peer("Org2", "peer0") 106 org3peer0 := setup.network.Peer("Org3", "peer0") 107 108 // Negative test: rollback, reset, pause, and resume should fail when the peer is online 109 expectedErrMessage := "as another peer node command is executing," + 110 " wait for that command to complete its execution or terminate it before retrying" 111 By("Rolling back the peer to block 6 from block 13 while the peer node is online") 112 helper.rollback(org1peer0, 6, expectedErrMessage, false) 113 By("Resetting the peer to the genesis block while the peer node is online") 114 helper.reset(org2peer0, expectedErrMessage, false) 115 By("Pausing the peer while the peer node is online") 116 helper.pause(org3peer0, expectedErrMessage, false) 117 By("Resuming the peer while the peer node is online") 118 helper.resume(org3peer0, expectedErrMessage, false) 119 120 By("Stopping the network to test commands") 121 setup.terminateAllProcess() 122 123 By("Rolling back the channel to block 6 from block 14 on org1peer0") 124 helper.rollback(org1peer0, 6, "", true) 125 126 By("Resetting org2peer0 to the genesis block") 127 helper.reset(org2peer0, "", true) 128 129 By("Pausing the channel on org3peer0") 130 helper.pause(org3peer0, "", true) 131 132 By("Rolling back the paused channel to block 6 from block 14 on org3peer0") 133 helper.rollback(org3peer0, 6, "", true) 134 135 By("Verifying paused channel is not found upon peer restart") 136 setup.startPeer(org3peer0) 137 helper.assertPausedChannel(org3peer0) 138 139 By("Checking preResetHeightFile exists for a paused channel that is also rolled back or reset") 140 setup.startBrokerAndOrderer() 141 preResetHeightFile := filepath.Join(setup.network.PeerLedgerDir(org3peer0), "chains/chains", helper.channelID, "__preResetHeight") 142 Expect(preResetHeightFile).To(BeARegularFile()) 143 144 setup.terminateAllProcess() 145 146 By("Resuming the peer") 147 helper.resume(org3peer0, "", true) 148 149 By("Verifying that the endorsement is disabled when the peer has not received missing blocks") 150 setup.startPeers() 151 for _, peer := range setup.peers { 152 helper.assertDisabledEndorser("marblesp", peer) 153 } 154 155 By("Bringing the peers to recent height by starting the orderer") 156 setup.startBrokerAndOrderer() 157 for _, peer := range setup.peers { 158 By("Verifying endorsement is enabled and preResetHeightFile is removed on peer " + peer.ID()) 159 helper.waitUntilEndorserEnabled(peer) 160 preResetHeightFile := filepath.Join(setup.network.PeerLedgerDir(peer), "chains/chains", helper.channelID, "__preResetHeight") 161 Expect(preResetHeightFile).NotTo(BeAnExistingFile()) 162 } 163 164 setup.network.VerifyMembership(setup.peers, setup.channelID, "marblesp") 165 166 By("Verifying leger height on all peers") 167 helper.waitUntilAllPeersEqualLedgerHeight(14) 168 169 // Test chaincode works correctly after the commands 170 By("Creating 2 more blocks post rollback/reset") 171 for i := 6; i <= 7; i++ { 172 helper.addMarble("marblesp", fmt.Sprintf(`{"name":"marble%d", "color":"blue", "size":35, "owner":"tom", "price":99}`, i), org2peer0) 173 helper.waitUntilAllPeersEqualLedgerHeight(14 + i - 5) 174 } 175 176 By("Verifying marble1 to marble7 exist in collectionMarbles & collectionMarblePrivateDetails on org2peer0") 177 for i := 1; i <= 7; i++ { 178 helper.assertPresentInCollectionM("marblesp", fmt.Sprintf("marble%d", i), org2peer0) 179 helper.assertPresentInCollectionMPD("marblesp", fmt.Sprintf("marble%d", i), org2peer0) 180 } 181 182 // statedb rebuild test 183 By("Stopping peers and deleting the statedb folder on peer Org2.peer0") 184 peer := setup.network.Peer("Org2", "peer0") 185 setup.stopPeers() 186 dbPath := filepath.Join(setup.network.PeerLedgerDir(peer), "stateLeveldb") 187 Expect(os.RemoveAll(dbPath)).NotTo(HaveOccurred()) 188 Expect(dbPath).NotTo(BeADirectory()) 189 By("Restarting the peer Org2.peer0") 190 setup.startPeer(peer) 191 Expect(dbPath).To(BeADirectory()) 192 helper.assertPresentInCollectionM("marblesp", "marble2", peer) 193 }) 194 195 // This test exercises peer node unjoin on the following peers: 196 // Org1.peer0 - unjoin 197 // Org2.peer0 - 198 // Org3.peer0 - unjoin (via partial / resumed deletion on restart) 199 It("unjoins channels and checks side effects on the ledger and transient storage", func() { 200 By("Checking ledger heights on each peer") 201 for _, peer := range helper.peers { 202 Expect(helper.getLedgerHeight(peer)).Should(Equal(14)) 203 } 204 205 org1peer0 := setup.network.Peer("Org1", "peer0") 206 org2peer0 := setup.network.Peer("Org2", "peer0") 207 org3peer0 := setup.network.Peer("Org3", "peer0") 208 209 // Negative test: peer node unjoin should fail when the peer is online. 210 By("unjoining the peer while the peer node is online") 211 expectedErrMessage := "as another peer node command is executing," + 212 " wait for that command to complete its execution or terminate it before retrying" 213 helper.unjoin(org1peer0, expectedErrMessage, false) 214 helper.unjoin(org2peer0, expectedErrMessage, false) 215 helper.unjoin(org3peer0, expectedErrMessage, false) 216 217 By("stopping the peers to test unjoin commands") 218 setup.stopPeers() 219 220 By("Unjoining from a channel while the peer is down") 221 helper.unjoin(org1peer0, "", true) 222 223 // Negative test: unjoin when the channel has been unjoined 224 By("Double unjoining from a channel") 225 expectedErrMessage = "unjoin channel \\[testchannel\\]: cannot update ledger status, ledger \\[testchannel\\] does not exist" 226 helper.unjoin(org1peer0, expectedErrMessage, false) 227 228 // Simulate an error in peer unjoin by marking the ledger folder as read-only. 229 By("Unjoining from a peer with a read-only ledger file system") 230 ledgerStoragePath := filepath.Join(setup.network.PeerLedgerDir(org3peer0), "chains/chains", helper.channelID) 231 Expect(os.Chmod(ledgerStoragePath, 0o555)).NotTo(HaveOccurred()) 232 Expect(os.RemoveAll(ledgerStoragePath)).To(HaveOccurred()) // can not delete write-only ledger folder 233 expectedErrMessage = "ledgersData/chains/chains/testchannel/blockfile_000000: permission denied" 234 helper.unjoin(org3peer0, expectedErrMessage, false) 235 Expect(os.Chmod(ledgerStoragePath, 0o755)).NotTo(HaveOccurred()) 236 237 By("restarting peers") 238 setup.startPeer(org1peer0) 239 setup.startPeer(org2peer0) 240 setup.startPeer(org3peer0) 241 242 helper.assertUnjoinedChannel(org1peer0) 243 helper.assertUnjoinedChannel(org3peer0) 244 245 By("rejoining the channel with org1") 246 setup.network.JoinChannel(helper.channelID, setup.orderer, org1peer0) 247 helper.waitUntilPeerEqualLedgerHeight(org1peer0, 14) 248 249 By("Creating 2 more blocks post re-join org1") 250 for i := 6; i <= 7; i++ { 251 helper.addMarble("marblesp", fmt.Sprintf(`{"name":"marble%d", "color":"blue", "size":35, "owner":"tom", "price":99}`, i), org1peer0) 252 helper.waitUntilPeerEqualLedgerHeight(org1peer0, 14+i-5) 253 helper.waitUntilPeerEqualLedgerHeight(org2peer0, 14+i-5) 254 } 255 }) 256 }) 257 258 type setup struct { 259 testDir string 260 channelID string 261 network *nwo.Network 262 peers []*nwo.Peer 263 peerProcess []ifrit.Process 264 orderer *nwo.Orderer 265 ordererProcess ifrit.Process 266 brokerProcess ifrit.Process 267 } 268 269 func initThreeOrgsSetup() *setup { 270 var err error 271 testDir, err := ioutil.TempDir("", "reset-rollback") 272 Expect(err).NotTo(HaveOccurred()) 273 274 client, err := docker.NewClientFromEnv() 275 Expect(err).NotTo(HaveOccurred()) 276 277 n := nwo.New(nwo.ThreeOrgSolo(), testDir, client, StartPort(), components) 278 n.GenerateConfigTree() 279 n.Bootstrap() 280 281 peers := []*nwo.Peer{ 282 n.Peer("Org1", "peer0"), 283 n.Peer("Org2", "peer0"), 284 n.Peer("Org3", "peer0"), 285 } 286 287 setup := &setup{ 288 testDir: testDir, 289 network: n, 290 peers: peers, 291 channelID: "testchannel", 292 } 293 294 setup.startBrokerAndOrderer() 295 296 setup.startPeer(peers[0]) 297 setup.startPeer(peers[1]) 298 setup.startPeer(peers[2]) 299 300 orderer := n.Orderer("orderer") 301 n.CreateAndJoinChannel(orderer, "testchannel") 302 n.UpdateChannelAnchors(orderer, "testchannel") 303 setup.orderer = orderer 304 305 By("verifying membership") 306 setup.network.VerifyMembership(setup.peers, setup.channelID) 307 308 return setup 309 } 310 311 func (s *setup) cleanup() { 312 s.terminateAllProcess() 313 s.network.Cleanup() 314 os.RemoveAll(s.testDir) 315 } 316 317 func (s *setup) terminateAllProcess() { 318 s.ordererProcess.Signal(syscall.SIGTERM) 319 Eventually(s.ordererProcess.Wait(), s.network.EventuallyTimeout).Should(Receive()) 320 s.ordererProcess = nil 321 322 s.brokerProcess.Signal(syscall.SIGTERM) 323 Eventually(s.brokerProcess.Wait(), s.network.EventuallyTimeout).Should(Receive()) 324 s.brokerProcess = nil 325 326 for _, p := range s.peerProcess { 327 p.Signal(syscall.SIGTERM) 328 Eventually(p.Wait(), s.network.EventuallyTimeout).Should(Receive()) 329 } 330 s.peerProcess = nil 331 } 332 333 func (s *setup) startPeers() { 334 for _, peer := range s.peers { 335 s.startPeer(peer) 336 } 337 } 338 339 func (s *setup) stopPeers() { 340 for _, p := range s.peerProcess { 341 p.Signal(syscall.SIGTERM) 342 Eventually(p.Wait(), s.network.EventuallyTimeout).Should(Receive()) 343 } 344 s.peerProcess = nil 345 } 346 347 func (s *setup) startPeer(peer *nwo.Peer) { 348 peerRunner := s.network.PeerRunner(peer) 349 peerProcess := ifrit.Invoke(peerRunner) 350 Eventually(peerProcess.Ready(), s.network.EventuallyTimeout).Should(BeClosed()) 351 s.peerProcess = append(s.peerProcess, peerProcess) 352 } 353 354 func (s *setup) startBrokerAndOrderer() { 355 brokerRunner := s.network.BrokerGroupRunner() 356 brokerProcess := ifrit.Invoke(brokerRunner) 357 Eventually(brokerProcess.Ready(), s.network.EventuallyTimeout).Should(BeClosed()) 358 s.brokerProcess = brokerProcess 359 360 ordererRunner := s.network.OrdererGroupRunner() 361 ordererProcess := ifrit.Invoke(ordererRunner) 362 Eventually(ordererProcess.Ready(), s.network.EventuallyTimeout).Should(BeClosed()) 363 s.ordererProcess = ordererProcess 364 } 365 366 type networkHelper struct { 367 *nwo.Network 368 orderer *nwo.Orderer 369 peers []*nwo.Peer 370 channelID string 371 testDir string 372 } 373 374 func (nh *networkHelper) deployChaincode(chaincode nwo.Chaincode) { 375 nwo.DeployChaincode(nh.Network, nh.channelID, nh.orderer, chaincode) 376 nh.waitUntilAllPeersEqualLedgerHeight(nh.getLedgerHeight(nh.peers[0])) 377 } 378 379 func (nh *networkHelper) waitUntilAllPeersEqualLedgerHeight(height int) { 380 for _, peer := range nh.peers { 381 nh.waitUntilPeerEqualLedgerHeight(peer, height) 382 } 383 } 384 385 func (nh *networkHelper) waitUntilPeerEqualLedgerHeight(peer *nwo.Peer, height int) { 386 Eventually(func() int { 387 return nh.getLedgerHeight(peer) 388 }, nh.EventuallyTimeout).Should(Equal(height)) 389 } 390 391 func (nh *networkHelper) getLedgerHeight(peer *nwo.Peer) int { 392 sess, err := nh.PeerUserSession(peer, "User1", commands.ChannelInfo{ 393 ChannelID: nh.channelID, 394 }) 395 Expect(err).NotTo(HaveOccurred()) 396 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 397 398 channelInfoStr := strings.TrimPrefix(string(sess.Buffer().Contents()[:]), "Blockchain info:") 399 channelInfo := common.BlockchainInfo{} 400 err = json.Unmarshal([]byte(channelInfoStr), &channelInfo) 401 Expect(err).NotTo(HaveOccurred()) 402 return int(channelInfo.Height) 403 } 404 405 func (nh *networkHelper) queryChaincode(peer *nwo.Peer, command commands.ChaincodeQuery, expectedMessage string, expectSuccess bool) { 406 sess, err := nh.PeerUserSession(peer, "User1", command) 407 Expect(err).NotTo(HaveOccurred()) 408 if expectSuccess { 409 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 410 Expect(sess).To(gbytes.Say(expectedMessage)) 411 } else { 412 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(1)) 413 Expect(sess.Err).To(gbytes.Say(expectedMessage)) 414 } 415 } 416 417 func (nh *networkHelper) invokeChaincode(peer *nwo.Peer, command commands.ChaincodeInvoke) { 418 sess, err := nh.PeerUserSession(peer, "User1", command) 419 Expect(err).NotTo(HaveOccurred()) 420 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 421 Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful.")) 422 } 423 424 func (nh *networkHelper) rollback(peer *nwo.Peer, blockNumber int, expectedErrMessage string, expectSuccess bool) { 425 rollbackCmd := commands.NodeRollback{ChannelID: nh.channelID, BlockNumber: blockNumber} 426 sess, err := nh.PeerUserSession(peer, "User1", rollbackCmd) 427 Expect(err).NotTo(HaveOccurred()) 428 if expectSuccess { 429 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 430 } else { 431 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(1)) 432 Expect(sess.Err).To(gbytes.Say(expectedErrMessage)) 433 } 434 } 435 436 func (nh *networkHelper) reset(peer *nwo.Peer, expectedErrMessage string, expectSuccess bool) { 437 resetCmd := commands.NodeReset{} 438 sess, err := nh.PeerUserSession(peer, "User1", resetCmd) 439 Expect(err).NotTo(HaveOccurred()) 440 if expectSuccess { 441 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 442 } else { 443 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(1)) 444 Expect(sess.Err).To(gbytes.Say(expectedErrMessage)) 445 } 446 } 447 448 func (nh *networkHelper) pause(peer *nwo.Peer, expectedErrMessage string, expectSuccess bool) { 449 pauseCmd := commands.NodePause{ChannelID: nh.channelID} 450 sess, err := nh.PeerUserSession(peer, "User1", pauseCmd) 451 Expect(err).NotTo(HaveOccurred()) 452 if expectSuccess { 453 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 454 } else { 455 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(1)) 456 Expect(sess.Err).To(gbytes.Say(expectedErrMessage)) 457 } 458 } 459 460 func (nh *networkHelper) resume(peer *nwo.Peer, expectedErrMessage string, expectSuccess bool) { 461 resumeCmd := commands.NodeResume{ChannelID: nh.channelID} 462 sess, err := nh.PeerUserSession(peer, "User1", resumeCmd) 463 Expect(err).NotTo(HaveOccurred()) 464 if expectSuccess { 465 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 466 } else { 467 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(1)) 468 Expect(sess.Err).To(gbytes.Say(expectedErrMessage)) 469 } 470 } 471 472 func (nh *networkHelper) unjoin(peer *nwo.Peer, expectedErrMessage string, expectSuccess bool) { 473 unjoinCmd := commands.NodeUnjoin{ChannelID: nh.channelID} 474 sess, err := nh.PeerUserSession(peer, "User1", unjoinCmd) 475 Expect(err).NotTo(HaveOccurred()) 476 if expectSuccess { 477 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(0)) 478 } else { 479 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit(1)) 480 Expect(sess.Err).To(gbytes.Say(expectedErrMessage)) 481 } 482 } 483 484 func (nh *networkHelper) waitUntilEndorserEnabled(peer *nwo.Peer) { 485 Eventually(func() *gbytes.Buffer { 486 sess, err := nh.PeerUserSession(peer, "User1", commands.ChannelInfo{ 487 ChannelID: nh.channelID, 488 }) 489 Expect(err).NotTo(HaveOccurred()) 490 Eventually(sess, nh.EventuallyTimeout).Should(gexec.Exit()) 491 return sess.Buffer() 492 }, nh.EventuallyTimeout).Should(gbytes.Say("Blockchain info")) 493 } 494 495 type testHelper struct { 496 *networkHelper 497 } 498 499 func (th *testHelper) addMarble(chaincodeName, marbleDetails string, peer *nwo.Peer) { 500 marbleDetailsBase64 := base64.StdEncoding.EncodeToString([]byte(marbleDetails)) 501 502 command := commands.ChaincodeInvoke{ 503 ChannelID: th.channelID, 504 Orderer: th.OrdererAddress(th.orderer, nwo.ListenPort), 505 Name: chaincodeName, 506 Ctor: `{"Args":["initMarble"]}`, 507 Transient: fmt.Sprintf(`{"marble":"%s"}`, marbleDetailsBase64), 508 PeerAddresses: []string{ 509 th.PeerAddress(peer, nwo.ListenPort), 510 }, 511 WaitForEvent: true, 512 } 513 th.invokeChaincode(peer, command) 514 } 515 516 // assertPresentInCollectionM asserts that the private data for given marble is present in collection 517 // 'readMarble' at the given peers 518 func (th *testHelper) assertPresentInCollectionM(chaincodeName, marbleName string, peerList ...*nwo.Peer) { 519 command := commands.ChaincodeQuery{ 520 ChannelID: th.channelID, 521 Name: chaincodeName, 522 Ctor: fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName), 523 } 524 expectedMsg := fmt.Sprintf(`{"docType":"marble","name":"%s"`, marbleName) 525 for _, peer := range peerList { 526 th.queryChaincode(peer, command, expectedMsg, true) 527 } 528 } 529 530 // assertPresentInCollectionMPD asserts that the private data for given marble is present 531 // in collection 'readMarblePrivateDetails' at the given peers 532 func (th *testHelper) assertPresentInCollectionMPD(chaincodeName, marbleName string, peerList ...*nwo.Peer) { 533 command := commands.ChaincodeQuery{ 534 ChannelID: th.channelID, 535 Name: chaincodeName, 536 Ctor: fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName), 537 } 538 expectedMsg := fmt.Sprintf(`{"docType":"marblePrivateDetails","name":"%s"`, marbleName) 539 for _, peer := range peerList { 540 th.queryChaincode(peer, command, expectedMsg, true) 541 } 542 } 543 544 func (th *testHelper) assertDisabledEndorser(chaincodeName string, peer *nwo.Peer) { 545 command := commands.ChaincodeQuery{ 546 ChannelID: th.channelID, 547 Name: chaincodeName, 548 Ctor: `{"Args":["readMarble","marble1"]}`, 549 } 550 expectedMsg := "endorse requests are blocked while ledgers are being rebuilt" 551 th.queryChaincode(peer, command, expectedMsg, false) 552 } 553 554 func (th *testHelper) assertPausedChannel(peer *nwo.Peer) { 555 sess, err := th.PeerUserSession(peer, "User1", commands.ChannelInfo{ 556 ChannelID: th.channelID, 557 }) 558 Expect(err).NotTo(HaveOccurred()) 559 Eventually(sess, th.EventuallyTimeout).Should(gexec.Exit(1)) 560 Expect(sess.Err).To(gbytes.Say("Invalid chain ID")) 561 } 562 563 func (th *testHelper) assertUnjoinedChannel(peer *nwo.Peer) { 564 sess, err := th.PeerUserSession(peer, "User1", commands.ChannelInfo{ 565 ChannelID: th.channelID, 566 }) 567 Expect(err).NotTo(HaveOccurred()) 568 Eventually(sess, th.EventuallyTimeout).Should(gexec.Exit(1)) 569 Expect(sess.Err).To(gbytes.Say("Invalid chain ID")) 570 571 channelLedgerDir := filepath.Join(th.Network.PeerLedgerDir(peer), "chains/chains", th.channelID) 572 Expect(channelLedgerDir).NotTo(BeADirectory()) 573 }