Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to use local test image tarball instead of building the image #495

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions internal/commands/test_tile.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ type TileTestFunction func(ctx context.Context, w io.Writer, configuration test.

type TileTest struct {
Options struct {
TilePath string ` long:"tile-path" default:"." description:"Path to the Tile directory (e.g., ~/workspace/tas/ist)."`
Verbose bool `short:"v" long:"verbose" default:"true" description:"Print info lines. This doesn't affect Ginkgo output."`
Silent bool `short:"s" long:"silent" default:"false" description:"Hide info lines. This doesn't affect Ginkgo output."`
Manifest bool ` long:"manifest" default:"false" description:"Focus the Manifest tests."`
Migrations bool ` long:"migrations" default:"false" description:"Focus the Migration tests."`
Stability bool ` long:"stability" default:"false" description:"Focus the Stability tests."`

TilePath string ` long:"tile-path" default:"." description:"Path to the Tile directory (e.g., ~/workspace/tas/ist)."`
Verbose bool `short:"v" long:"verbose" default:"true" description:"Print info lines. This doesn't affect Ginkgo output."`
Silent bool `short:"s" long:"silent" default:"false" description:"Hide info lines. This doesn't affect Ginkgo output."`
Manifest bool ` long:"manifest" default:"false" description:"Focus the Manifest tests."`
Migrations bool ` long:"migrations" default:"false" description:"Focus the Migration tests."`
Stability bool ` long:"stability" default:"false" description:"Focus the Stability tests."`
ImagePath string ` long:"image-path" `
EnvironmentVars []string `short:"e" long:"environment-variable" description:"Pass environment variable to the test suites. For example --stability -e 'PRODUCT=srt'."`
GingkoFlags string ` long:"ginkgo-flags" default:"-r -p -slowSpecThreshold 15" description:"Flags to pass to the Ginkgo Manifest and Stability test suites."`
}
Expand Down Expand Up @@ -70,6 +70,7 @@ func (cmd TileTest) configuration() (test.Configuration, error) {
RunManifest: cmd.Options.Manifest,
RunMetadata: cmd.Options.Stability,
RunMigrations: cmd.Options.Migrations,
ImagePath: cmd.Options.ImagePath,

GinkgoFlags: cmd.Options.GingkoFlags,
Environment: cmd.Options.EnvironmentVars,
Expand Down
21 changes: 21 additions & 0 deletions internal/commands/test_tile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,27 @@ var _ = Describe("kiln test", func() {
})
})

When("when the a test image is provided via --image-path", func() {
It("it sets the path to be loaded in the configuration", func() {
args := []string{"--image-path", "/tmp/test.file"}

fakeTestFunc := fakes.TestTileFunction{}
fakeTestFunc.Returns(nil)

err := commands.NewTileTestWithCollaborators(&output, fakeTestFunc.Spy).Execute(args)
Expect(err).NotTo(HaveOccurred())

Expect(fakeTestFunc.CallCount()).To(Equal(1))

ctx, w, configuration := fakeTestFunc.ArgsForCall(0)
Expect(ctx).NotTo(BeNil())
Expect(w).NotTo(BeNil())
Expect(configuration.ImagePath).To(Equal("/tmp/test.file"))
Expect(configuration.RunManifest).To(BeFalse())
Expect(configuration.RunMetadata).To(BeFalse())
Expect(configuration.RunMigrations).To(BeFalse())
})
})
When("when the stability test is enabled", func() {
It("it sets the metadata configuration flag", func() {
args := []string{"--stability"}
Expand Down
1 change: 1 addition & 0 deletions internal/test/assets/alpine.tgz
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

48 changes: 36 additions & 12 deletions internal/test/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type Configuration struct {
RunMigrations,
RunManifest,
RunMetadata bool
ImagePath string

GinkgoFlags string
Environment []string
Expand Down Expand Up @@ -123,6 +124,7 @@ func (configuration Configuration) commands() ([]string, error) {
//counterfeiter:generate -o ./fakes/moby_client.go --fake-name MobyClient . mobyClient
type mobyClient interface {
DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error)
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error)
ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
Ping(ctx context.Context) (types.Ping, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specV1.Platform, containerName string) (container.CreateResponse, error)
Expand All @@ -140,22 +142,44 @@ func runTestWithSession(ctx context.Context, logger *log.Logger, w io.Writer, do
}

var dockerfileTarball bytes.Buffer
if err := createDockerfileTarball(tar.NewWriter(&dockerfileTarball), dockerfile); err != nil {
if err = createDockerfileTarball(tar.NewWriter(&dockerfileTarball), dockerfile); err != nil {
return err
}

logger.Println("creating test image")
imageBuildResult, err := dockerDaemon.ImageBuild(ctx, &dockerfileTarball, types.ImageBuildOptions{
Tags: []string{"kiln_test_dependencies:vmware"},
Version: types.BuilderBuildKit,
SessionID: sessionID,
})
if err != nil {
return fmt.Errorf("failed to build image: %w", err)
}
if configuration.ImagePath == "" {
logger.Println("creating test image")
imageBuildResult, err := dockerDaemon.ImageBuild(ctx, &dockerfileTarball, types.ImageBuildOptions{
Tags: []string{"kiln_test_dependencies:vmware"},
Version: types.BuilderBuildKit,
SessionID: sessionID,
})
if err != nil {
return fmt.Errorf("failed to build image: %w", err)
}
if err = checkSSHPrivateKeyError(imageBuildResult.Body); err != nil {
return err
}
} else {
logger.Println("loading test image")
imageReader, err := os.Open(configuration.ImagePath)
if err != nil {
return fmt.Errorf("failed to read image '%s': %w", configuration.ImagePath, err)
}

if err := checkSSHPrivateKeyError(imageBuildResult.Body); err != nil {
return err
loadResponse, err := dockerDaemon.ImageLoad(
ctx,
imageReader,
true,
)
if err != nil {
return fmt.Errorf("failed to import image: %w", err)
}
defer closeAndIgnoreError(loadResponse.Body)
respBytes, err := io.ReadAll(loadResponse.Body)
if err != nil {
return fmt.Errorf(`failed to parse load image response: %w`, err)
}
logger.Printf("loaded image %s: \n%s\n", configuration.ImagePath, string(respBytes))
}

parentDir := path.Dir(configuration.AbsoluteTileDirectory)
Expand Down
41 changes: 41 additions & 0 deletions internal/test/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,43 @@ func Test_configureSession(t *testing.T) {
})
}

func Test_loadImage(t *testing.T) {
absoluteTileDirectory := filepath.Join(t.TempDir(), "test")
logger := log.New(io.Discard, "", 0)
t.Run("when loading a provided test image with a wrong path", func(t *testing.T) {
ctx := context.Background()
out := bytes.Buffer{}
configuration := Configuration{
AbsoluteTileDirectory: absoluteTileDirectory,
ImagePath: "non-existing",
}
client := runTestWithSessionHelper(t, "", container.WaitResponse{
StatusCode: 0,
})

err := runTestWithSession(ctx, logger, &out, client, configuration)("some-session-id")
require.ErrorContains(t, err, "failed to read image 'non-existing': open non-existing: no such file or directory")

})
t.Run(`when loading a provided test image with an existing path`, func(t *testing.T) {
ctx := context.Background()
out := bytes.Buffer{}

configuration := Configuration{
AbsoluteTileDirectory: absoluteTileDirectory,
ImagePath: "assets/alpine.tgz",
}

client := runTestWithSessionHelper(t, "", container.WaitResponse{
StatusCode: 0,
})

err := runTestWithSession(ctx, logger, &out, client, configuration)("some-session-id")
require.NoError(t, err)

})
}

func Test_runTestWithSession(t *testing.T) {
absoluteTileDirectory := filepath.Join(t.TempDir(), "test")
logger := log.New(io.Discard, "", 0)
Expand Down Expand Up @@ -200,6 +237,10 @@ func runTestWithSessionHelper(t *testing.T, logs string, response container.Wait
client.ImageBuildReturns(types.ImageBuildResponse{
Body: io.NopCloser(strings.NewReader("")),
}, nil)
client.ImageLoadReturns(types.ImageLoadResponse{
Body: io.NopCloser(strings.NewReader("")),
}, nil)

client.ContainerStartReturns(nil)
client.ContainerLogsReturns(io.NopCloser(strings.NewReader(logs)), nil)

Expand Down
168 changes: 168 additions & 0 deletions internal/test/fakes/moby_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading