Skip to content

Commit eb84de6

Browse files
committed
[FAB-11001] Direct errors to stderr, not stdout
When incorrect commandline arguments are passed, the output is directed to stdout instead of stderr. This change set fixes this, and also makes sub-commands that return error to terminate with error code of 1 instead of 0. Change-Id: I3e9c2172d91b25829e5b9c81aa3e812a205c9cf5 Signed-off-by: yacovm <yacovm@il.ibm.com>
1 parent 683c099 commit eb84de6

File tree

5 files changed

+67
-17
lines changed

5 files changed

+67
-17
lines changed

cmd/common/cli.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ const (
2525
var (
2626
// Function used to terminate the CLI
2727
terminate = os.Exit
28-
// Function used to obtain the stdout
29-
outWriter io.Writer = os.Stdout
28+
// Function used to redirect output to
29+
outWriter io.Writer = os.Stderr
3030

3131
// CLI arguments
3232
mspID *string
@@ -91,6 +91,8 @@ func (cli *CLI) Run(args []string) {
9191
err := f(conf)
9292
if err != nil {
9393
out(err)
94+
terminate(1)
95+
return
9496
}
9597
}
9698

@@ -153,5 +155,5 @@ func evaluateFileFlag(f **os.File) string {
153155
return path
154156
}
155157
func out(a ...interface{}) {
156-
fmt.Fprintln(outWriter, a)
158+
fmt.Fprintln(outWriter, a...)
157159
}

cmd/common/cli_test.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"os"
1717

1818
"github.com/hyperledger/fabric/cmd/common/signer"
19+
"github.com/pkg/errors"
1920
"github.com/stretchr/testify/assert"
2021
)
2122

@@ -30,6 +31,7 @@ func TestCLI(t *testing.T) {
3031
testBuff := &bytes.Buffer{}
3132
outWriter = testBuff
3233

34+
var returnValue error
3335
cli := NewCLI("cli", "cli help")
3436
testCommand := func(conf Config) error {
3537
// If we exited, the command wasn't executed
@@ -46,7 +48,7 @@ func TestCLI(t *testing.T) {
4648
},
4749
}, conf)
4850
testCmdInvoked = true
49-
return nil
51+
return returnValue
5052
}
5153
cli.Command("test", "test help", testCommand)
5254

@@ -60,7 +62,7 @@ func TestCLI(t *testing.T) {
6062
assert.True(t, exited)
6163
})
6264

63-
t.Run("Loading a valid config", func(t *testing.T) {
65+
t.Run("Loading a valid config and the command succeeds", func(t *testing.T) {
6466
defer testBuff.Reset()
6567
testCmdInvoked = false
6668
exited = false
@@ -69,6 +71,24 @@ func TestCLI(t *testing.T) {
6971
// Ensure that a valid config results in running our command
7072
cli.Run([]string{"test", "--configFile", filepath.Join(dir, "config.yaml")})
7173
assert.True(t, testCmdInvoked)
74+
assert.False(t, exited)
75+
})
76+
77+
t.Run("Loading a valid config but the command fails", func(t *testing.T) {
78+
returnValue = errors.New("something went wrong")
79+
defer func() {
80+
returnValue = nil
81+
}()
82+
defer testBuff.Reset()
83+
testCmdInvoked = false
84+
exited = false
85+
// Overwrite user home directory with testdata
86+
dir := filepath.Join("testdata", "valid_config")
87+
// Ensure that a valid config results in running our command
88+
cli.Run([]string{"test", "--configFile", filepath.Join(dir, "config.yaml")})
89+
assert.True(t, testCmdInvoked)
90+
assert.True(t, exited)
91+
assert.Contains(t, testBuff.String(), "something went wrong")
7292
})
7393

7494
t.Run("Saving a config", func(t *testing.T) {

cmd/discover/main_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package main
8+
9+
import (
10+
"os/exec"
11+
"testing"
12+
13+
. "github.com/onsi/gomega"
14+
"github.com/onsi/gomega/gbytes"
15+
. "github.com/onsi/gomega/gexec"
16+
)
17+
18+
func TestMissingArguments(t *testing.T) {
19+
gt := NewGomegaWithT(t)
20+
discover, err := Build("github.com/hyperledger/fabric/cmd/discover")
21+
gt.Expect(err).NotTo(HaveOccurred())
22+
defer CleanupBuildArtifacts()
23+
24+
// key and cert flags are missing
25+
cmd := exec.Command(discover, "--configFile", "conf.yaml", "--MSP", "SampleOrg", "saveConfig")
26+
process, err := Start(cmd, nil, nil)
27+
gt.Expect(err).NotTo(HaveOccurred())
28+
gt.Eventually(process).Should(Exit(1))
29+
gt.Expect(process.Err).To(gbytes.Say("empty string that is mandatory"))
30+
}

integration/discovery_service/e2e_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ var _ = Describe("DiscoveryService EndToEnd", func() {
190190
By("discover endorsers, shouldn't get a valid result since cc was not installed yet")
191191
sdRunner := sd.DiscoverEndorsers(d.Channel, "127.0.0.1:7051", "mycc", "")
192192
err := helpers.Execute(sdRunner)
193-
Expect(err).NotTo(HaveOccurred())
194-
Expect(sdRunner.Buffer()).Should(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
193+
Expect(err).To(HaveOccurred())
194+
Expect(sdRunner.Err()).Should(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
195195

196196
By("install and instantiate chaincode on p0.org1")
197197
adminPeer := getPeer(0, 1, testDir)
@@ -209,8 +209,8 @@ var _ = Describe("DiscoveryService EndToEnd", func() {
209209
By("discover endorsers, shouldn't get a valid result since cc was not installed on sufficient number of orgs yet")
210210
sdRunner = sd.DiscoverEndorsers(d.Channel, "127.0.0.1:7051", "mycc", "")
211211
err = helpers.Execute(sdRunner)
212-
Expect(err).NotTo(HaveOccurred())
213-
Expect(sdRunner.Buffer()).Should(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
212+
Expect(err).To(HaveOccurred())
213+
Expect(sdRunner.Err()).Should(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
214214

215215
By("install chaincode on p0.org2")
216216
adminPeer = getPeer(0, 2, testDir)
@@ -254,14 +254,13 @@ var _ = Describe("DiscoveryService EndToEnd", func() {
254254
EventuallyWithOffset(1, func() bool {
255255
return runner.VerifyEndorsersDiscovered(sd, expectedChaincodeEndrorsers3, d.Channel, "127.0.0.1:7051", "mycc", "collectionMarbles")
256256
}, time.Minute).Should(BeTrue())
257-
Expect(err).NotTo(HaveOccurred())
258257
By("remove org3 members (except admin) from channel writers")
259258
sendChannelConfigUpdate(0, 3, d.Channel, d.Orderer, testDir)
260259
By("try to discover peers using org3, should get access denied")
261260
sdRunner = sd.DiscoverPeers(d.Channel, "127.0.0.1:9051")
262261
err = helpers.Execute(sdRunner)
263-
Expect(err).NotTo(HaveOccurred())
264-
Expect(sdRunner.Buffer()).Should(gbytes.Say("access denied"))
262+
Expect(err).To(HaveOccurred())
263+
Expect(sdRunner.Err()).Should(gbytes.Say("access denied"))
265264
})
266265
})
267266

integration/runner/discovery_service.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"os"
1414
"os/exec"
1515
"path/filepath"
16-
"strings"
1716

1817
"github.com/hyperledger/fabric/integration/helpers"
1918
"github.com/hyperledger/fabric/protos/discovery"
@@ -142,13 +141,13 @@ func VerifyConfigDiscovered(sd *DiscoveryService, expectedConfig discovery.Confi
142141

143142
func VerifyEndorsersDiscovered(sd *DiscoveryService, expectedEndorsementDescriptor helpers.EndorsementDescriptor, channel string, server string, chaincodeName string, collectionName string) bool {
144143
sdRunner := sd.DiscoverEndorsers(channel, server, chaincodeName, collectionName)
145-
err := helpers.Execute(sdRunner)
146-
Expect(err).NotTo(HaveOccurred())
147-
if strings.Contains(string(sdRunner.Buffer().Contents()[:]), fmt.Sprintf(`failed constructing descriptor for chaincodes:<name:"%s"`, chaincodeName)) {
144+
if err := helpers.Execute(sdRunner); err != nil {
148145
return false
149146
}
150147
var endorsers []helpers.EndorsementDescriptor
151-
json.Unmarshal(sdRunner.Buffer().Contents(), &endorsers)
148+
if err := json.Unmarshal(sdRunner.Buffer().Contents(), &endorsers); err != nil {
149+
return false
150+
}
152151

153152
return helpers.CheckEndorsementContainsExpectedEndorsement(expectedEndorsementDescriptor, endorsers[0]) &&
154153
helpers.CheckEndorsementContainsExpectedEndorsement(endorsers[0], expectedEndorsementDescriptor)

0 commit comments

Comments
 (0)