Skip to content

Commit 07e0478

Browse files
committed
Added more unit tests
1 parent ec05eb2 commit 07e0478

File tree

5 files changed

+145
-74
lines changed

5 files changed

+145
-74
lines changed

api/bundle/client.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ var logger = loggo.GetLogger("juju.api.bundle")
1919
// Client allows access to the bundle API end point.
2020
type Client struct {
2121
base.ClientFacade
22-
st base.APICallCloser
2322
facade base.FacadeCaller
2423
}
2524

@@ -28,7 +27,6 @@ func NewClient(st base.APICallCloser) *Client {
2827
frontend, backend := base.NewClientFacade(st, "Bundle")
2928
return &Client{
3029
ClientFacade: frontend,
31-
st: st,
3230
facade: backend}
3331
}
3432

@@ -40,11 +38,8 @@ func (c *Client) ExportBundle() (string, error) {
4038
}
4139

4240
if err := c.facade.FacadeCall("ExportBundle", nil, &result); err != nil {
43-
return "", errors.Trace(err)
41+
return "", errors.Annotate(result.Error, "export failed")
4442
}
4543

46-
if len(result.Result) == 0 {
47-
return "", errors.Errorf("result obtained is incorrect")
48-
}
4944
return result.Result, nil
5045
}

api/bundle/client_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func (s *bundleMockSuite) TestExportBundlev2(c *gc.C) {
5959
c.Check(id, gc.Equals, "")
6060
c.Check(request, gc.Equals, "ExportBundle")
6161
c.Assert(args, gc.Equals, nil)
62+
c.Assert(response, gc.FitsTypeOf, &params.StringResult{})
6263
result := response.(*params.StringResult)
6364
result.Result = "applications:\n " +
6465
"ubuntu:\n " +
@@ -90,3 +91,27 @@ func (s *bundleMockSuite) TestExportBundlev2(c *gc.C) {
9091
"relations:\n"+
9192
"- []\n")
9293
}
94+
95+
func (s *bundleMockSuite) TestExportBundleErrorv2(c *gc.C) {
96+
client := newClient(
97+
func(objType string, version int,
98+
id,
99+
request string,
100+
args,
101+
response interface{},
102+
) error {
103+
c.Check(objType, gc.Equals, "Bundle")
104+
c.Check(id, gc.Equals, "")
105+
c.Check(request, gc.Equals, "ExportBundle")
106+
c.Assert(args, gc.Equals, nil)
107+
c.Assert(response, gc.FitsTypeOf, &params.StringResult{})
108+
result := response.(*params.StringResult)
109+
result.Result = ""
110+
return result.Error
111+
}, 2,
112+
)
113+
result, err := client.ExportBundle()
114+
c.Assert(err, gc.NotNil)
115+
c.Assert(result, jc.DeepEquals, "")
116+
c.Check(err.Error(), jc.Contains, "export failed")
117+
}

cmd/juju/model/export_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,10 @@ func NewDumpDBCommandForTest(api DumpDBAPI, store jujuclient.ClientStore) cmd.Co
6868
}
6969

7070
// NewDumpCommandForTest returns a DumpCommand with the api provided as specified.
71-
func NewExportBundleCommandForTest(api ExportBundleModelAPI, store jujuclient.ClientStore) cmd.Command {
72-
cmd := &exportBundleCommand{api: api}
71+
func NewExportBundleCommandForTest(api ExportBundleAPI, store jujuclient.ClientStore) cmd.Command {
72+
cmd := &exportBundleCommand{newAPIFunc: func() (ExportBundleAPI, error) {
73+
return api, nil
74+
}}
7375
cmd.SetClientStore(store)
7476
return modelcmd.Wrap(cmd)
7577
}

cmd/juju/model/exportbundle.go

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,30 @@
33
package model
44

55
import (
6-
"fmt"
7-
"os"
8-
96
"github.com/juju/cmd"
10-
"github.com/juju/errors"
117
"github.com/juju/gnuflag"
128

9+
"fmt"
10+
"github.com/juju/errors"
1311
"github.com/juju/juju/api/bundle"
1412
"github.com/juju/juju/cmd/modelcmd"
1513
"github.com/juju/juju/cmd/output"
14+
"os"
1615
)
1716

1817
// NewExportBundleCommand returns a fully constructed export bundle command.
1918
func NewExportBundleCommand() cmd.Command {
20-
return modelcmd.Wrap(&exportBundleCommand{})
19+
cmd := &exportBundleCommand{}
20+
cmd.newAPIFunc = func() (ExportBundleAPI, error) {
21+
return cmd.getAPI()
22+
}
23+
return modelcmd.Wrap(cmd)
2124
}
2225

2326
type exportBundleCommand struct {
2427
modelcmd.ModelCommandBase
25-
out cmd.Output
26-
api ExportBundleModelAPI
28+
out cmd.Output
29+
newAPIFunc func() (ExportBundleAPI, error)
2730
// name of the charm bundle file.
2831
Filename string
2932
}
@@ -60,58 +63,52 @@ func (c *exportBundleCommand) Init(args []string) error {
6063
}
6164

6265
// ExportBundleAPI specifies the used function calls of the ModelManager.
63-
type ExportBundleModelAPI interface {
66+
type ExportBundleAPI interface {
6467
Close() error
6568
BestAPIVersion() int
6669
ExportBundle() (string, error)
6770
}
6871

69-
func (c *exportBundleCommand) getAPI() (ExportBundleModelAPI, error) {
70-
if c.api != nil {
71-
return c.api, nil
72-
}
73-
72+
func (c *exportBundleCommand) getAPI() (ExportBundleAPI, error) {
7473
api, err := c.NewAPIRoot()
7574
if err != nil {
76-
return nil, errors.Trace(err)
75+
return nil, err
7776
}
77+
7878
return bundle.NewClient(api), nil
7979
}
8080

8181
// Run implements Command.
8282
func (c *exportBundleCommand) Run(ctx *cmd.Context) error {
83-
client, err := c.getAPI()
83+
client, err := c.newAPIFunc()
8484
if err != nil {
8585
return err
8686
}
8787
defer client.Close()
8888

89-
var result string
90-
if client.BestAPIVersion() > 1 {
91-
result, err = client.ExportBundle()
92-
if err != nil {
93-
return err
94-
}
89+
result, err := client.ExportBundle()
90+
if err != nil {
91+
return err
92+
}
93+
94+
if c.Filename == "" {
95+
return c.out.Write(ctx, result)
9596
}
97+
filename := c.Filename + ".yaml"
98+
file, err := os.Create(filename)
99+
if err != nil {
100+
return errors.Annotate(err, "while creating local file")
101+
}
102+
defer file.Close()
96103

97-
if c.Filename != "" {
98-
filename := c.Filename + ".yaml"
99-
file, err := os.Create(filename)
100-
if err != nil {
101-
return errors.Annotate(err, "while creating local file")
102-
}
103-
defer file.Close()
104-
105-
// Write out the result.
106-
_, err = file.WriteString(result)
107-
if err != nil {
108-
return errors.Annotate(err, "while copying in local file")
109-
}
110-
111-
// Print the local filename.
112-
fmt.Fprintln(ctx.Stdout, "Bundle successfully exported to", filename)
113-
} else {
114-
c.out.Write(ctx, result)
104+
// Write out the result.
105+
_, err = file.WriteString(result)
106+
if err != nil {
107+
return errors.Annotate(err, "while copying in local file")
115108
}
109+
110+
// Print the local filename.
111+
fmt.Fprintln(ctx.Stdout, "Bundle successfully exported to", filename)
112+
116113
return nil
117114
}

cmd/juju/model/exportbundle_test.go

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package model_test
55

66
import (
77
"github.com/juju/cmd/cmdtesting"
8+
"github.com/juju/errors"
89
jujutesting "github.com/juju/testing"
910
jc "github.com/juju/testing/checkers"
1011
gc "gopkg.in/check.v1"
@@ -24,37 +25,15 @@ type ExportBundleCommandSuite struct {
2425

2526
var _ = gc.Suite(&ExportBundleCommandSuite{})
2627

27-
type fakeExportBundleClient struct {
28-
*jujutesting.Stub
29-
bestAPIVersion int
30-
}
31-
3228
func (f *fakeExportBundleClient) Close() error { return nil }
3329

3430
func (f *fakeExportBundleClient) ExportBundle() (string, error) {
3531
f.MethodCall(f, "ExportBundle")
3632
if err := f.NextErr(); err != nil {
3733
return "", err
3834
}
39-
return "applications:\n" +
40-
" mysql:\n" +
41-
" charm: \"\"\n" +
42-
" num_units: 1\n" +
43-
" to:\n" +
44-
" - \"0\"\n" +
45-
" wordpress:\n" +
46-
" charm: \"\"\n" +
47-
" num_units: 2\n" +
48-
" to:\n" +
49-
" - \"0\"\n" +
50-
" - \"1\"\n" +
51-
"machines:\n" +
52-
" \"0\": {}\n" +
53-
" \"1\": {}\n" +
54-
"series: xenial\n" +
55-
"relations:\n" +
56-
"- - wordpress:db\n" +
57-
" - mysql:mysql\n", f.NextErr()
35+
36+
return f.result, f.NextErr()
5837
}
5938

6039
func (f *fakeExportBundleClient) BestAPIVersion() int {
@@ -65,8 +44,7 @@ func (s *ExportBundleCommandSuite) SetUpTest(c *gc.C) {
6544
s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
6645
s.stub = &jujutesting.Stub{}
6746
s.fake = &fakeExportBundleClient{
68-
Stub: s.stub,
69-
bestAPIVersion: 2,
47+
Stub: s.stub,
7048
}
7149
s.store = jujuclient.NewMemStore()
7250
s.store.CurrentControllerName = "testing"
@@ -82,7 +60,62 @@ func (s *ExportBundleCommandSuite) SetUpTest(c *gc.C) {
8260
s.store.Models["testing"].CurrentModel = "admin/mymodel"
8361
}
8462

85-
func (s *ExportBundleCommandSuite) TestExportBundleNoFilename(c *gc.C) {
63+
func (s *ExportBundleCommandSuite) TestExportBundleFailOnv1(c *gc.C) {
64+
s.fake.result = ""
65+
s.fake.Stub.SetErrors(errors.New("command not supported on v1"))
66+
s.fake.bestAPIVersion = 1
67+
68+
ctx, err := cmdtesting.RunCommand(c, model.NewExportBundleCommandForTest(s.fake, s.store))
69+
c.Assert(err, gc.NotNil)
70+
71+
s.fake.CheckCalls(c, []jujutesting.StubCall{
72+
{"ExportBundle", nil},
73+
})
74+
75+
out := cmdtesting.Stdout(ctx)
76+
c.Assert(out, gc.Equals, "")
77+
c.Assert(err, gc.ErrorMatches, "command not supported on v1")
78+
}
79+
80+
func (s *ExportBundleCommandSuite) TestExportBundleFailEmptyResult(c *gc.C) {
81+
s.fake.result = ""
82+
s.fake.Stub.SetErrors(errors.New("export failed: nothing to export as there are no applications"))
83+
s.fake.bestAPIVersion = 2
84+
85+
ctx, err := cmdtesting.RunCommand(c, model.NewExportBundleCommandForTest(s.fake, s.store))
86+
c.Assert(err, gc.NotNil)
87+
88+
s.fake.CheckCalls(c, []jujutesting.StubCall{
89+
{"ExportBundle", nil},
90+
})
91+
92+
out := cmdtesting.Stdout(ctx)
93+
c.Assert(out, gc.Equals, "")
94+
c.Assert(err, gc.ErrorMatches, "export failed: nothing to export as there are no applications")
95+
}
96+
97+
func (s *ExportBundleCommandSuite) TestExportBundleSuccessNoFilename(c *gc.C) {
98+
s.fake.result = "applications:\n" +
99+
" mysql:\n" +
100+
" charm: \"\"\n" +
101+
" num_units: 1\n" +
102+
" to:\n" +
103+
" - \"0\"\n" +
104+
" wordpress:\n" +
105+
" charm: \"\"\n" +
106+
" num_units: 2\n" +
107+
" to:\n" +
108+
" - \"0\"\n" +
109+
" - \"1\"\n" +
110+
"machines:\n" +
111+
" \"0\": {}\n" +
112+
" \"1\": {}\n" +
113+
"series: xenial\n" +
114+
"relations:\n" +
115+
"- - wordpress:db\n" +
116+
" - mysql:mysql\n"
117+
s.fake.bestAPIVersion = 2
118+
86119
ctx, err := cmdtesting.RunCommand(c, model.NewExportBundleCommandForTest(s.fake, s.store))
87120
c.Assert(err, jc.ErrorIsNil)
88121
s.fake.CheckCalls(c, []jujutesting.StubCall{
@@ -111,3 +144,22 @@ func (s *ExportBundleCommandSuite) TestExportBundleNoFilename(c *gc.C) {
111144
" - - wordpress:db\n"+
112145
" - mysql:mysql\n")
113146
}
147+
148+
func (s *ExportBundleCommandSuite) TestExportBundleSuccessFilename(c *gc.C) {
149+
s.fake.bestAPIVersion = 2
150+
151+
ctx, err := cmdtesting.RunCommand(c, model.NewExportBundleCommandForTest(s.fake, s.store), "--filename", "mymodel")
152+
c.Assert(err, jc.ErrorIsNil)
153+
s.fake.CheckCalls(c, []jujutesting.StubCall{
154+
{"ExportBundle", nil},
155+
})
156+
157+
out := cmdtesting.Stdout(ctx)
158+
c.Assert(out, gc.Equals, "Bundle successfully exported to mymodel.yaml\n")
159+
}
160+
161+
type fakeExportBundleClient struct {
162+
*jujutesting.Stub
163+
bestAPIVersion int
164+
result string
165+
}

0 commit comments

Comments
 (0)