-
Notifications
You must be signed in to change notification settings - Fork 292
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add tests for extension_package command
Signed-off-by: Darshan Kumar <itsdarshankumar@gmail.com>
- Loading branch information
1 parent
dd4f694
commit e9a6172
Showing
2 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,321 @@ | ||
package commands_test | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/heroku/color" | ||
"github.com/pkg/errors" | ||
"github.com/sclevine/spec" | ||
"github.com/sclevine/spec/report" | ||
"github.com/spf13/cobra" | ||
|
||
pubbldpkg "github.com/buildpacks/pack/buildpackage" | ||
"github.com/buildpacks/pack/internal/commands" | ||
"github.com/buildpacks/pack/internal/commands/fakes" | ||
"github.com/buildpacks/pack/internal/config" | ||
"github.com/buildpacks/pack/pkg/dist" | ||
"github.com/buildpacks/pack/pkg/image" | ||
"github.com/buildpacks/pack/pkg/logging" | ||
h "github.com/buildpacks/pack/testhelpers" | ||
) | ||
|
||
func TestExtensionPackageCommand(t *testing.T) { | ||
color.Disable(true) | ||
defer color.Disable(false) | ||
spec.Run(t, "ExtensionPackageCommand", testExtensionPackageCommand, spec.Parallel(), spec.Report(report.Terminal{})) | ||
} | ||
|
||
func testExtensionPackageCommand(t *testing.T, when spec.G, it spec.S) { | ||
var ( | ||
logger *logging.LogWithWriters | ||
outBuf bytes.Buffer | ||
) | ||
|
||
it.Before(func() { | ||
logger = logging.NewLogWithWriters(&outBuf, &outBuf) | ||
}) | ||
|
||
when("Package#Execute", func() { | ||
var fakeExtensionPackager *fakes.FakeBuildpackPackager | ||
|
||
it.Before(func() { | ||
fakeExtensionPackager = &fakes.FakeBuildpackPackager{} | ||
}) | ||
|
||
when("valid package config", func() { | ||
it("reads package config from the configured path", func() { | ||
fakePackageConfigReader := fakes.NewFakePackageConfigReader() | ||
expectedPackageConfigPath := "/path/to/some/file" | ||
|
||
cmd := packageExtensionCommand( | ||
withExtensionPackageConfigReader(fakePackageConfigReader), | ||
withExtensionPackageConfigPath(expectedPackageConfigPath), | ||
) | ||
err := cmd.Execute() | ||
h.AssertNil(t, err) | ||
|
||
h.AssertEq(t, fakePackageConfigReader.ReadCalledWithArg, expectedPackageConfigPath) | ||
}) | ||
|
||
it("creates package with correct image name", func() { | ||
cmd := packageExtensionCommand( | ||
withExtensionImageName("my-specific-image"), | ||
withExtensionPackager(fakeExtensionPackager), | ||
) | ||
err := cmd.Execute() | ||
h.AssertNil(t, err) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.Name, "my-specific-image") | ||
}) | ||
|
||
it("creates package with config returned by the reader", func() { | ||
myConfig := pubbldpkg.Config{ | ||
Extension: dist.BuildpackURI{URI: "test"}, | ||
} | ||
|
||
cmd := packageExtensionCommand( | ||
withExtensionPackager(fakeExtensionPackager), | ||
withExtensionPackageConfigReader(fakes.NewFakePackageConfigReader(whereReadReturns(myConfig, nil))), | ||
) | ||
err := cmd.Execute() | ||
h.AssertNil(t, err) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.Config, myConfig) | ||
}) | ||
|
||
when("file format", func() { | ||
when("extension is .cnb", func() { | ||
it("does not modify the name", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager)) | ||
cmd.SetArgs([]string{"test.cnb", "-f", "file"}) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.Name, "test.cnb") | ||
}) | ||
}) | ||
when("extension is empty", func() { | ||
it("appends .cnb to the name", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager)) | ||
cmd.SetArgs([]string{"test", "-f", "file"}) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.Name, "test.cnb") | ||
}) | ||
}) | ||
when("extension is something other than .cnb", func() { | ||
it("does not modify the name but shows a warning", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager), withExtensionLogger(logger)) | ||
cmd.SetArgs([]string{"test.tar.gz", "-f", "file"}) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.Name, "test.tar.gz") | ||
h.AssertContains(t, outBuf.String(), "'.gz' is not a valid extension for a packaged extension. Packaged extensions must have a '.cnb' extension") | ||
}) | ||
}) | ||
}) | ||
|
||
when("pull-policy", func() { | ||
var pullPolicyArgs = []string{ | ||
"some-image-name", | ||
"--config", "/path/to/some/file", | ||
"--pull-policy", | ||
} | ||
|
||
it("pull-policy=never sets policy", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager)) | ||
cmd.SetArgs(append(pullPolicyArgs, "never")) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.PullPolicy, image.PullNever) | ||
}) | ||
|
||
it("pull-policy=always sets policy", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager)) | ||
cmd.SetArgs(append(pullPolicyArgs, "always")) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.PullPolicy, image.PullAlways) | ||
}) | ||
}) | ||
when("no --pull-policy", func() { | ||
var pullPolicyArgs = []string{ | ||
"some-image-name", | ||
"--config", "/path/to/some/file", | ||
} | ||
|
||
it("uses the default policy when no policy configured", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager)) | ||
cmd.SetArgs(pullPolicyArgs) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.PullPolicy, image.PullAlways) | ||
}) | ||
it("uses the configured pull policy when policy configured", func() { | ||
cmd := packageExtensionCommand( | ||
withExtensionPackager(fakeExtensionPackager), | ||
withExtensionClientConfig(config.Config{PullPolicy: "never"}), | ||
) | ||
|
||
cmd.SetArgs([]string{ | ||
"some-image-name", | ||
"--config", "/path/to/some/file", | ||
}) | ||
|
||
err := cmd.Execute() | ||
h.AssertNil(t, err) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.PullPolicy, image.PullNever) | ||
}) | ||
}) | ||
}) | ||
|
||
when("no config path is specified", func() { | ||
when("no path is specified", func() { | ||
it("creates a default config with the uri set to the current working directory", func() { | ||
cmd := packageExtensionCommand(withExtensionPackager(fakeExtensionPackager)) | ||
cmd.SetArgs([]string{"some-name"}) | ||
h.AssertNil(t, cmd.Execute()) | ||
|
||
receivedOptions := fakeExtensionPackager.CreateCalledWithOptions | ||
h.AssertEq(t, receivedOptions.Config.Extension.URI, ".") | ||
}) | ||
}) | ||
}) | ||
}) | ||
|
||
when("invalid flags", func() { | ||
when("both --publish and --pull-policy never flags are specified", func() { | ||
it("errors with a descriptive message", func() { | ||
cmd := packageExtensionCommand() | ||
cmd.SetArgs([]string{ | ||
"some-image-name", "--config", "/path/to/some/file", | ||
"--publish", | ||
"--pull-policy", "never", | ||
}) | ||
|
||
err := cmd.Execute() | ||
h.AssertNotNil(t, err) | ||
h.AssertError(t, err, "--publish and --pull-policy never cannot be used together. The --publish flag requires the use of remote images.") | ||
}) | ||
}) | ||
|
||
it("logs an error and exits when package toml is invalid", func() { | ||
expectedErr := errors.New("it went wrong") | ||
|
||
cmd := packageExtensionCommand( | ||
withExtensionLogger(logger), | ||
withExtensionPackageConfigReader( | ||
fakes.NewFakePackageConfigReader(whereReadReturns(pubbldpkg.Config{}, expectedErr)), | ||
), | ||
) | ||
|
||
err := cmd.Execute() | ||
h.AssertNotNil(t, err) | ||
|
||
h.AssertContains(t, outBuf.String(), fmt.Sprintf("ERROR: reading config: %s", expectedErr)) | ||
}) | ||
|
||
when("package-config is specified", func() { | ||
it("errors with a descriptive message", func() { | ||
cmd := packageExtensionCommand() | ||
cmd.SetArgs([]string{"some-name", "--package-config", "some-path"}) | ||
|
||
err := cmd.Execute() | ||
h.AssertError(t, err, "unknown flag: --package-config") | ||
}) | ||
}) | ||
|
||
when("--pull-policy unknown-policy", func() { | ||
it("fails to run", func() { | ||
cmd := packageExtensionCommand() | ||
cmd.SetArgs([]string{ | ||
"some-image-name", | ||
"--config", "/path/to/some/file", | ||
"--pull-policy", | ||
"unknown-policy", | ||
}) | ||
|
||
h.AssertError(t, cmd.Execute(), "parsing pull policy") | ||
}) | ||
}) | ||
}) | ||
} | ||
|
||
type packageExtensionCommandConfig struct { | ||
logger *logging.LogWithWriters | ||
packageConfigReader *fakes.FakePackageConfigReader | ||
extensionPackager *fakes.FakeBuildpackPackager | ||
clientConfig config.Config | ||
imageName string | ||
configPath string | ||
} | ||
|
||
type packageExtensionCommandOption func(config *packageExtensionCommandConfig) | ||
|
||
func packageExtensionCommand(ops ...packageExtensionCommandOption) *cobra.Command { | ||
config := &packageExtensionCommandConfig{ | ||
logger: logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}), | ||
packageConfigReader: fakes.NewFakePackageConfigReader(), | ||
extensionPackager: &fakes.FakeBuildpackPackager{}, | ||
clientConfig: config.Config{}, | ||
imageName: "some-image-name", | ||
configPath: "/path/to/some/file", | ||
} | ||
|
||
for _, op := range ops { | ||
op(config) | ||
} | ||
|
||
cmd := commands.ExtensionPackage(config.logger, config.clientConfig, config.extensionPackager, config.packageConfigReader) | ||
cmd.SetArgs([]string{config.imageName, "--config", config.configPath}) | ||
|
||
return cmd | ||
} | ||
|
||
func withExtensionLogger(logger *logging.LogWithWriters) packageExtensionCommandOption { | ||
return func(config *packageExtensionCommandConfig) { | ||
config.logger = logger | ||
} | ||
} | ||
|
||
func withExtensionPackageConfigReader(reader *fakes.FakePackageConfigReader) packageExtensionCommandOption { | ||
return func(config *packageExtensionCommandConfig) { | ||
config.packageConfigReader = reader | ||
} | ||
} | ||
|
||
func withExtensionPackager(creator *fakes.FakeBuildpackPackager) packageExtensionCommandOption { | ||
return func(config *packageExtensionCommandConfig) { | ||
config.extensionPackager = creator | ||
} | ||
} | ||
|
||
func withExtensionImageName(name string) packageExtensionCommandOption { | ||
return func(config *packageExtensionCommandConfig) { | ||
config.imageName = name | ||
} | ||
} | ||
|
||
func withExtensionPackageConfigPath(path string) packageExtensionCommandOption { | ||
return func(config *packageExtensionCommandConfig) { | ||
config.configPath = path | ||
} | ||
} | ||
|
||
func withExtensionClientConfig(clientCfg config.Config) packageExtensionCommandOption { | ||
return func(config *packageExtensionCommandConfig) { | ||
config.clientConfig = clientCfg | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package fakes | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/buildpacks/pack/pkg/client" | ||
) | ||
|
||
func (c *FakeBuildpackPackager) PackageExtension(ctx context.Context, opts client.PackageBuildpackOptions) error { | ||
c.CreateCalledWithOptions = opts | ||
|
||
return nil | ||
} |