@@ -532,134 +532,188 @@ 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 (
535+ Describe ("Update" , func () {
536+ var envelopePath string
537+
538+ BeforeEach (func () {
539+ configEnvelope := envelopeUpdateConfigWithGroups (
538540 map [string ]* cb.ConfigGroup {
539541 "Application" : {},
540542 },
541543 "testing123" ,
542544 )
543- blockPath := createBlockFile (tempDir , configBlock )
544- mockChannelManagement .JoinChannelReturns (types.ChannelInfo {
545- Name : "apple" ,
546- ConsensusRelation : "banana" ,
547- Status : "orange" ,
548- Height : 123 ,
545+ envelopePath = createEnvelopeFile (tempDir , configEnvelope )
546+
547+ mockChannelManagement .UpdateChannelReturns (types.ChannelInfo {
548+ Name : "apple" ,
549+ Height : 123 ,
549550 }, nil )
551+ })
550552
553+ It ("uses the channel participation API to join a channel" , func () {
551554 args := []string {
552555 "channel" ,
553- "join " ,
554- "-o " , ordererURL ,
555- "-c " , channelID ,
556- "-b " , blockPath ,
556+ "update " ,
557+ "--orderer-address " , ordererURL ,
558+ "--channelID " , channelID ,
559+ "--config-update-envelope " , envelopePath ,
557560 "--ca-file" , ordererCACert ,
558561 "--client-cert" , clientCert ,
559562 "--client-key" , clientKey ,
560563 }
561564 output , exit , err := executeForArgs (args )
562565 expectedOutput := types.ChannelInfo {
563- Name : "apple" ,
564- URL : "/participation/v1/channels/apple" ,
565- ConsensusRelation : "banana" ,
566- Status : "orange" ,
567- Height : 123 ,
566+ Name : "apple" ,
567+ URL : "/participation/v1/channels/apple" ,
568+ Height : 123 ,
568569 }
569570 checkStatusOutput (output , exit , err , 201 , expectedOutput )
570571 })
571572
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'" ))
573+ Context ("when the envelope is empty" , func () {
574+ BeforeEach (func () {
575+ envelopePath = createEnvelopeFile (tempDir , & cb.Envelope {})
576576 })
577577
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'" ))
578+ It ("returns with exit code 1 and prints the error" , func () {
579+ args := []string {
580+ "channel" ,
581+ "update" ,
582+ "--orderer-address" , ordererURL ,
583+ "--channelID" , channelID ,
584+ "--config-update-envelope" , envelopePath ,
585+ "--ca-file" , ordererCACert ,
586+ "--client-cert" , clientCert ,
587+ "--client-key" , clientKey ,
588+ }
589+ output , exit , err := executeForArgs (args )
590+
591+ checkFlagError (output , exit , err , "failed to retrieve channel id - payload header is empty" )
581592 })
582593 })
583594
584- Context ("when the ca cert cannot be read " , func () {
595+ Context ("when the --channelID does not match the channel ID in the envelope " , func () {
585596 BeforeEach (func () {
586- ordererCACert = "not-the-ca-cert -youre-looking-for"
597+ channelID = "not-the-channel -youre-looking-for"
587598 })
588599
589600 It ("returns with exit code 1 and prints the error" , func () {
590601 args := []string {
591602 "channel" ,
592- "list " ,
603+ "update " ,
593604 "--orderer-address" , ordererURL ,
594605 "--channelID" , channelID ,
606+ "--config-update-envelope" , envelopePath ,
595607 "--ca-file" , ordererCACert ,
596608 "--client-cert" , clientCert ,
597609 "--client-key" , clientKey ,
598610 }
599611 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" )
612+
613+ checkFlagError (output , exit , err , "specified --channelID not-the-channel-youre-looking-for does not match channel ID testing123 in config update envelope" )
601614 })
602615 })
603616
604- Context ("when the ca-file contains a private key instead of certificate(s) " , func () {
617+ Context ("when the envelope isn't a valid config update " , func () {
605618 BeforeEach (func () {
606- ordererCACert = clientKey
619+ envelope := & cb.Envelope {
620+ Payload : protoutil .MarshalOrPanic (& cb.Payload {
621+ Header : & cb.Header {
622+ ChannelHeader : protoutil .MarshalOrPanic (& cb.ChannelHeader {
623+ Type : int32 (cb .HeaderType_ENDORSER_TRANSACTION ),
624+ ChannelId : channelID ,
625+ }),
626+ },
627+ }),
628+ }
629+ envelopePath = createEnvelopeFile (tempDir , envelope )
607630 })
608631
609- It ("returns with exit code 1 and prints the error " , func () {
632+ It ("returns 405 bad request " , func () {
610633 args := []string {
611634 "channel" ,
612- "remove " ,
635+ "update " ,
613636 "--orderer-address" , ordererURL ,
614637 "--channelID" , channelID ,
638+ "--config-update-envelope" , envelopePath ,
615639 "--ca-file" , ordererCACert ,
616640 "--client-cert" , clientCert ,
617641 "--client-key" , clientKey ,
618642 }
619643 output , exit , err := executeForArgs (args )
620- checkFlagError (output , exit , err , "failed to add ca-file PEM to cert pool" )
644+ Expect (err ).NotTo (HaveOccurred ())
645+ Expect (exit ).To (Equal (0 ))
646+
647+ expectedOutput := types.ErrorResponse {
648+ Error : "invalid config update envelope: bad type" ,
649+ }
650+ checkStatusOutput (output , exit , err , 400 , expectedOutput )
621651 })
622652 })
623653
624- Context ("when the client cert/key pair fail to load " , func () {
654+ Context ("when updating the channel fails " , func () {
625655 BeforeEach (func () {
626- clientKey = "brussel-sprouts"
656+ mockChannelManagement . UpdateChannelReturns (types. ChannelInfo {}, types . ErrChannelNotExist )
627657 })
628658
629- It ("returns with exit code 1 and prints the error " , func () {
659+ It ("returns 405 not allowed " , func () {
630660 args := []string {
631661 "channel" ,
632- "list " ,
662+ "update " ,
633663 "--orderer-address" , ordererURL ,
664+ "--channelID" , channelID ,
665+ "--config-update-envelope" , envelopePath ,
634666 "--ca-file" , ordererCACert ,
635667 "--client-cert" , clientCert ,
636668 "--client-key" , clientKey ,
637669 }
638670 output , exit , err := executeForArgs (args )
639- checkFlagError (output , exit , err , "loading client cert/key pair: open brussel-sprouts: no such file or directory" )
671+ expectedOutput := types.ErrorResponse {
672+ Error : "cannot update: channel does not exist" ,
673+ }
674+ checkStatusOutput (output , exit , err , 405 , expectedOutput )
640675 })
641- })
642676
643- Context ("when the config block cannot be read" , func () {
644- var configBlockPath string
677+ It ("returns 405 not allowed (without status)" , func () {
678+ args := []string {
679+ "channel" ,
680+ "update" ,
681+ "--orderer-address" , ordererURL ,
682+ "--channelID" , channelID ,
683+ "--config-update-envelope" , envelopePath ,
684+ "--ca-file" , ordererCACert ,
685+ "--client-cert" , clientCert ,
686+ "--client-key" , clientKey ,
687+ "--no-status" ,
688+ }
689+ output , exit , err := executeForArgs (args )
690+ expectedOutput := types.ErrorResponse {
691+ Error : "cannot update: channel does not exist" ,
692+ }
693+ checkOutput (output , exit , err , expectedOutput )
694+ })
695+ })
645696
697+ Context ("when TLS is disabled" , func () {
646698 BeforeEach (func () {
647- configBlockPath = "not-the-config-block-youre-looking-for"
699+ tlsConfig = nil
648700 })
649701
650- It ("returns with exit code 1 and prints the error " , func () {
702+ It ("uses the channel participation API to join a channel " , func () {
651703 args := []string {
652704 "channel" ,
653- "join " ,
705+ "update " ,
654706 "--orderer-address" , ordererURL ,
655707 "--channelID" , channelID ,
656- "--ca-file" , ordererCACert ,
657- "--client-cert" , clientCert ,
658- "--client-key" , clientKey ,
659- "--config-block" , configBlockPath ,
708+ "--config-update-envelope" , envelopePath ,
660709 }
661710 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" )
711+ expectedOutput := types.ChannelInfo {
712+ Name : "apple" ,
713+ URL : "/participation/v1/channels/apple" ,
714+ Height : 123 ,
715+ }
716+ checkStatusOutput (output , exit , err , 201 , expectedOutput )
663717 })
664718 })
665719 })
@@ -834,3 +888,51 @@ func createBlockFile(tempDir string, configBlock *cb.Block) string {
834888 Expect (err ).NotTo (HaveOccurred ())
835889 return blockPath
836890}
891+
892+ func envelopeUpdateConfigWithGroups (groups map [string ]* cb.ConfigGroup , channelID string ) * cb.Envelope {
893+ data := & cb.Envelope {
894+ Payload : protoutil .MarshalOrPanic (& cb.Payload {
895+ Data : protoutil .MarshalOrPanic (& cb.ConfigEnvelope {
896+ Config : & cb.Config {
897+ ChannelGroup : & cb.ConfigGroup {
898+ Groups : groups ,
899+ Values : map [string ]* cb.ConfigValue {
900+ "HashingAlgorithm" : {
901+ Value : protoutil .MarshalOrPanic (& cb.HashingAlgorithm {
902+ Name : bccsp .SHA256 ,
903+ }),
904+ },
905+ "BlockDataHashingStructure" : {
906+ Value : protoutil .MarshalOrPanic (& cb.BlockDataHashingStructure {
907+ Width : math .MaxUint32 ,
908+ }),
909+ },
910+ "OrdererAddresses" : {
911+ Value : protoutil .MarshalOrPanic (& cb.OrdererAddresses {
912+ Addresses : []string {"localhost" },
913+ }),
914+ },
915+ },
916+ },
917+ },
918+ }),
919+ Header : & cb.Header {
920+ ChannelHeader : protoutil .MarshalOrPanic (& cb.ChannelHeader {
921+ Type : int32 (cb .HeaderType_CONFIG_UPDATE ),
922+ ChannelId : channelID ,
923+ }),
924+ },
925+ }),
926+ }
927+
928+ return data
929+ }
930+
931+ func createEnvelopeFile (tempDir string , configEnvelope * cb.Envelope ) string {
932+ envelopeBytes , err := proto .Marshal (configEnvelope )
933+ Expect (err ).NotTo (HaveOccurred ())
934+ envelopePath := filepath .Join (tempDir , "envelope.pb" )
935+ err = os .WriteFile (envelopePath , envelopeBytes , 0o644 )
936+ Expect (err ).NotTo (HaveOccurred ())
937+ return envelopePath
938+ }
0 commit comments