@@ -532,134 +532,183 @@ var _ = Describe("osnadmin", func() {
532532 })
533533 })
534534
535- Describe ("Flags" , func () {
536- It ("accepts short versions of the --orderer-address, --channelID, and --config-block flags" , func () {
537- configBlock := blockWithGroups (
538- map [string ]* cb.ConfigGroup {
539- "Application" : {},
540- },
541- "testing123" ,
542- )
543- blockPath := createBlockFile (tempDir , configBlock )
544- mockChannelManagement .JoinChannelReturns (types.ChannelInfo {
545- Name : "apple" ,
546- ConsensusRelation : "banana" ,
547- Status : "orange" ,
548- Height : 123 ,
535+ Describe ("Update" , func () {
536+ var envelopePath string
537+
538+ BeforeEach (func () {
539+ configEnvelope := envelopeUpdateConfigWithGroups ("testing123" )
540+ envelopePath = createEnvelopeFile (tempDir , configEnvelope )
541+
542+ mockChannelManagement .UpdateChannelReturns (types.ChannelInfo {
543+ Name : "apple" ,
544+ Height : 123 ,
549545 }, nil )
546+ })
550547
548+ It ("uses the channel participation API to update a channel" , func () {
551549 args := []string {
552550 "channel" ,
553- "join " ,
554- "-o " , ordererURL ,
555- "-c " , channelID ,
556- "-b " , blockPath ,
551+ "update " ,
552+ "--orderer-address " , ordererURL ,
553+ "--channelID " , channelID ,
554+ "--config-update-envelope " , envelopePath ,
557555 "--ca-file" , ordererCACert ,
558556 "--client-cert" , clientCert ,
559557 "--client-key" , clientKey ,
560558 }
561559 output , exit , err := executeForArgs (args )
562560 expectedOutput := types.ChannelInfo {
563- Name : "apple" ,
564- URL : "/participation/v1/channels/apple" ,
565- ConsensusRelation : "banana" ,
566- Status : "orange" ,
567- Height : 123 ,
561+ Name : "apple" ,
562+ URL : "/participation/v1/channels/apple" ,
563+ Height : 123 ,
568564 }
569565 checkStatusOutput (output , exit , err , 201 , expectedOutput )
570566 })
571567
572- Context ("when an unknown flag is used" , func () {
573- It ("returns an error for long flags" , func () {
574- _ , _ , err := executeForArgs ([]string {"channel" , "list" , "--bad-flag" })
575- Expect (err ).To (MatchError ("unknown long flag '--bad-flag'" ))
568+ Context ("when the envelope is empty" , func () {
569+ BeforeEach (func () {
570+ envelopePath = createEnvelopeFile (tempDir , & cb.Envelope {})
576571 })
577572
578- It ("returns an error for short flags" , func () {
579- _ , _ , err := executeForArgs ([]string {"channel" , "list" , "-z" })
580- Expect (err ).To (MatchError ("unknown short flag '-z'" ))
573+ It ("returns with exit code 1 and prints the error" , func () {
574+ args := []string {
575+ "channel" ,
576+ "update" ,
577+ "--orderer-address" , ordererURL ,
578+ "--channelID" , channelID ,
579+ "--config-update-envelope" , envelopePath ,
580+ "--ca-file" , ordererCACert ,
581+ "--client-cert" , clientCert ,
582+ "--client-key" , clientKey ,
583+ }
584+ output , exit , err := executeForArgs (args )
585+
586+ checkFlagError (output , exit , err , "failed to retrieve channel id - payload header is empty" )
581587 })
582588 })
583589
584- Context ("when the ca cert cannot be read " , func () {
590+ Context ("when the --channelID does not match the channel ID in the envelope " , func () {
585591 BeforeEach (func () {
586- ordererCACert = "not-the-ca-cert -youre-looking-for"
592+ channelID = "not-the-channel -youre-looking-for"
587593 })
588594
589595 It ("returns with exit code 1 and prints the error" , func () {
590596 args := []string {
591597 "channel" ,
592- "list " ,
598+ "update " ,
593599 "--orderer-address" , ordererURL ,
594600 "--channelID" , channelID ,
601+ "--config-update-envelope" , envelopePath ,
595602 "--ca-file" , ordererCACert ,
596603 "--client-cert" , clientCert ,
597604 "--client-key" , clientKey ,
598605 }
599606 output , exit , err := executeForArgs (args )
600- checkFlagError (output , exit , err , "reading orderer CA certificate: open not-the-ca-cert-youre-looking-for: no such file or directory" )
607+
608+ checkFlagError (output , exit , err , "specified --channelID not-the-channel-youre-looking-for does not match channel ID testing123 in config update envelope" )
601609 })
602610 })
603611
604- Context ("when the ca-file contains a private key instead of certificate(s) " , func () {
612+ Context ("when the envelope isn't a valid config update " , func () {
605613 BeforeEach (func () {
606- ordererCACert = clientKey
614+ envelope := & cb.Envelope {
615+ Payload : protoutil .MarshalOrPanic (& cb.Payload {
616+ Header : & cb.Header {
617+ ChannelHeader : protoutil .MarshalOrPanic (& cb.ChannelHeader {
618+ Type : int32 (cb .HeaderType_ENDORSER_TRANSACTION ),
619+ ChannelId : channelID ,
620+ }),
621+ },
622+ }),
623+ }
624+ envelopePath = createEnvelopeFile (tempDir , envelope )
607625 })
608626
609- It ("returns with exit code 1 and prints the error " , func () {
627+ It ("returns 405 bad request " , func () {
610628 args := []string {
611629 "channel" ,
612- "remove " ,
630+ "update " ,
613631 "--orderer-address" , ordererURL ,
614632 "--channelID" , channelID ,
633+ "--config-update-envelope" , envelopePath ,
615634 "--ca-file" , ordererCACert ,
616635 "--client-cert" , clientCert ,
617636 "--client-key" , clientKey ,
618637 }
619638 output , exit , err := executeForArgs (args )
620- checkFlagError (output , exit , err , "failed to add ca-file PEM to cert pool" )
639+ Expect (err ).NotTo (HaveOccurred ())
640+ Expect (exit ).To (Equal (0 ))
641+
642+ expectedOutput := types.ErrorResponse {
643+ Error : "invalid config update envelope: bad type" ,
644+ }
645+ checkStatusOutput (output , exit , err , 400 , expectedOutput )
621646 })
622647 })
623648
624- Context ("when the client cert/key pair fail to load " , func () {
649+ Context ("when updating the channel fails " , func () {
625650 BeforeEach (func () {
626- clientKey = "brussel-sprouts"
651+ mockChannelManagement . UpdateChannelReturns (types. ChannelInfo {}, types . ErrChannelNotExist )
627652 })
628653
629- It ("returns with exit code 1 and prints the error " , func () {
654+ It ("returns 405 not allowed " , func () {
630655 args := []string {
631656 "channel" ,
632- "list " ,
657+ "update " ,
633658 "--orderer-address" , ordererURL ,
659+ "--channelID" , channelID ,
660+ "--config-update-envelope" , envelopePath ,
634661 "--ca-file" , ordererCACert ,
635662 "--client-cert" , clientCert ,
636663 "--client-key" , clientKey ,
637664 }
638665 output , exit , err := executeForArgs (args )
639- checkFlagError (output , exit , err , "loading client cert/key pair: open brussel-sprouts: no such file or directory" )
666+ expectedOutput := types.ErrorResponse {
667+ Error : "cannot update: channel does not exist" ,
668+ }
669+ checkStatusOutput (output , exit , err , 405 , expectedOutput )
640670 })
641- })
642671
643- Context ("when the config block cannot be read" , func () {
644- var configBlockPath string
672+ It ("returns 405 not allowed (without status)" , func () {
673+ args := []string {
674+ "channel" ,
675+ "update" ,
676+ "--orderer-address" , ordererURL ,
677+ "--channelID" , channelID ,
678+ "--config-update-envelope" , envelopePath ,
679+ "--ca-file" , ordererCACert ,
680+ "--client-cert" , clientCert ,
681+ "--client-key" , clientKey ,
682+ "--no-status" ,
683+ }
684+ output , exit , err := executeForArgs (args )
685+ expectedOutput := types.ErrorResponse {
686+ Error : "cannot update: channel does not exist" ,
687+ }
688+ checkOutput (output , exit , err , expectedOutput )
689+ })
690+ })
645691
692+ Context ("when TLS is disabled" , func () {
646693 BeforeEach (func () {
647- configBlockPath = "not-the-config-block-youre-looking-for"
694+ tlsConfig = nil
648695 })
649696
650- It ("returns with exit code 1 and prints the error " , func () {
697+ It ("uses the channel participation API to join a channel " , func () {
651698 args := []string {
652699 "channel" ,
653- "join " ,
700+ "update " ,
654701 "--orderer-address" , ordererURL ,
655702 "--channelID" , channelID ,
656- "--ca-file" , ordererCACert ,
657- "--client-cert" , clientCert ,
658- "--client-key" , clientKey ,
659- "--config-block" , configBlockPath ,
703+ "--config-update-envelope" , envelopePath ,
660704 }
661705 output , exit , err := executeForArgs (args )
662- checkFlagError (output , exit , err , "reading config block: open not-the-config-block-youre-looking-for: no such file or directory" )
706+ expectedOutput := types.ChannelInfo {
707+ Name : "apple" ,
708+ URL : "/participation/v1/channels/apple" ,
709+ Height : 123 ,
710+ }
711+ checkStatusOutput (output , exit , err , 201 , expectedOutput )
663712 })
664713 })
665714 })
@@ -834,3 +883,34 @@ func createBlockFile(tempDir string, configBlock *cb.Block) string {
834883 Expect (err ).NotTo (HaveOccurred ())
835884 return blockPath
836885}
886+
887+ func envelopeUpdateConfigWithGroups (channelID string ) * cb.Envelope {
888+ data := & cb.Envelope {
889+ Payload : protoutil .MarshalOrPanic (& cb.Payload {
890+ Data : protoutil .MarshalOrPanic (& cb.ConfigUpdateEnvelope {
891+ ConfigUpdate : protoutil .MarshalOrPanic (& cb.ConfigUpdate {
892+ ChannelId : channelID ,
893+ ReadSet : & cb.ConfigGroup {},
894+ WriteSet : & cb.ConfigGroup {},
895+ }),
896+ }),
897+ Header : & cb.Header {
898+ ChannelHeader : protoutil .MarshalOrPanic (& cb.ChannelHeader {
899+ Type : int32 (cb .HeaderType_CONFIG_UPDATE ),
900+ ChannelId : channelID ,
901+ }),
902+ },
903+ }),
904+ }
905+
906+ return data
907+ }
908+
909+ func createEnvelopeFile (tempDir string , configEnvelope * cb.Envelope ) string {
910+ envelopeBytes , err := proto .Marshal (configEnvelope )
911+ Expect (err ).NotTo (HaveOccurred ())
912+ envelopePath := filepath .Join (tempDir , "envelope.pb" )
913+ err = os .WriteFile (envelopePath , envelopeBytes , 0o644 )
914+ Expect (err ).NotTo (HaveOccurred ())
915+ return envelopePath
916+ }
0 commit comments