Permalink
Browse files

*: further test improvements [82%]

Removed unused code, added tests and cleaned up some test code. We've
now hit the ~80% coverage target. So it's looking much better than
before.

Signed-off-by: Aleksa Sarai <asarai@suse.com>
  • Loading branch information...
1 parent 39261ed commit 830921cf355d0c3e6cb3a918ccb9f89a95883157 @cyphar committed Dec 29, 2016
Showing with 486 additions and 80 deletions.
  1. +0 −14 cmd/umoci/tag.go
  2. +0 −19 cmd/umoci/unpack.go
  3. +149 −0 oci/cas/cas_test.go
  4. +11 −39 oci/generate/spec.go
  5. +293 −0 oci/generate/spec_test.go
  6. +5 −0 test/create.bats
  7. +10 −8 test/helpers.bash
  8. +18 −0 test/stat.bats
View
@@ -21,25 +21,11 @@ import (
"fmt"
"github.com/cyphar/umoci/oci/cas"
- ispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/urfave/cli"
"golang.org/x/net/context"
)
-func isValidMediaType(mediaType string) bool {
- validTypes := map[string]struct{}{
- ispec.MediaTypeImageManifest: {},
- ispec.MediaTypeImageManifestList: {},
- ispec.MediaTypeImageConfig: {},
- ispec.MediaTypeDescriptor: {},
- ispec.MediaTypeImageLayer: {},
- ispec.MediaTypeImageLayerNonDistributable: {},
- }
- _, ok := validTypes[mediaType]
- return ok
-}
-
var tagAddCommand = cli.Command{
Name: "tag",
Usage: "creates a new tag in an OCI image",
View
@@ -80,25 +80,6 @@ creation with umoci-repack(1).`,
},
}
-func getConfig(ctx context.Context, engine cas.Engine, manDescriptor *ispec.Descriptor) (ispec.Image, error) {
- // FIXME: Implement support for manifest lists.
- if manDescriptor.MediaType != ispec.MediaTypeImageManifest {
- return ispec.Image{}, errors.Wrap(fmt.Errorf("descriptor does not point to ispec.MediaTypeImageManifest: not implemented: %s", manDescriptor.MediaType), "invalid --image tag")
- }
-
- manBlob, err := cas.FromDescriptor(ctx, engine, manDescriptor)
- if err != nil {
- return ispec.Image{}, err
- }
-
- configBlob, err := cas.FromDescriptor(ctx, engine, &manBlob.Data.(*ispec.Manifest).Config)
- if err != nil {
- return ispec.Image{}, err
- }
-
- return *configBlob.Data.(*ispec.Image), nil
-}
-
func unpack(ctx *cli.Context) error {
imagePath := ctx.App.Metadata["--image-path"].(string)
fromName := ctx.App.Metadata["--image-tag"].(string)
View
@@ -68,6 +68,11 @@ func TestCreateLayout(t *testing.T) {
} else if len(blobs) > 0 {
t.Errorf("got blobs in a newly created image: %v", blobs)
}
+
+ // We should get an error if we try to create a new image atop an old one.
+ if err := CreateLayout(image); err == nil {
+ t.Errorf("expected to get a cowardly no-clobber error!")
+ }
}
func TestEngineBlob(t *testing.T) {
@@ -298,3 +303,147 @@ func TestEngineReference(t *testing.T) {
}
}
}
+
+func TestEngineValidate(t *testing.T) {
+ root, err := ioutil.TempDir("", "umoci-TestEngineValidate")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(root)
+
+ var engine Engine
+ var image string
+
+ // Empty directory.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // Invalid oci-layout.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(image, layoutFile), []byte("invalid JSON"), 0644); err != nil {
+ t.Fatal(err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // Invalid oci-layout.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(image, layoutFile), []byte("{}"), 0644); err != nil {
+ t.Fatal(err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // Missing blobdir.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Remove(image); err != nil {
+ t.Fatal(err)
+ }
+ if err := CreateLayout(image); err != nil {
+ t.Fatalf("unexpected error creating image: %+v", err)
+ }
+ if err := os.RemoveAll(filepath.Join(image, blobDirectory)); err != nil {
+ t.Fatalf("unexpected error deleting blobdir: %+v", err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // blobdir is not a directory.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Remove(image); err != nil {
+ t.Fatal(err)
+ }
+ if err := CreateLayout(image); err != nil {
+ t.Fatalf("unexpected error creating image: %+v", err)
+ }
+ if err := os.RemoveAll(filepath.Join(image, blobDirectory)); err != nil {
+ t.Fatalf("unexpected error deleting blobdir: %+v", err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(image, blobDirectory), []byte(""), 0755); err != nil {
+ t.Fatal(err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // Missing refdir.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Remove(image); err != nil {
+ t.Fatal(err)
+ }
+ if err := CreateLayout(image); err != nil {
+ t.Fatalf("unexpected error creating image: %+v", err)
+ }
+ if err := os.RemoveAll(filepath.Join(image, refDirectory)); err != nil {
+ t.Fatalf("unexpected error deleting refdir: %+v", err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // refdir is not a directory.
+ image, err = ioutil.TempDir(root, "image")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Remove(image); err != nil {
+ t.Fatal(err)
+ }
+ if err := CreateLayout(image); err != nil {
+ t.Fatalf("unexpected error creating image: %+v", err)
+ }
+ if err := os.RemoveAll(filepath.Join(image, refDirectory)); err != nil {
+ t.Fatalf("unexpected error deleting refdir: %+v", err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(image, refDirectory), []byte(""), 0755); err != nil {
+ t.Fatal(err)
+ }
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+
+ // No such directory.
+ image = filepath.Join(root, "non-exist")
+ engine, err = Open(image)
+ if err == nil {
+ t.Errorf("expected to get an error")
+ engine.Close()
+ }
+}
View
@@ -18,15 +18,11 @@
package generate
import (
- "encoding/json"
"fmt"
- "io"
- "os"
"strings"
"time"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
- "github.com/pkg/errors"
)
// FIXME: Because we are not a part of upstream, we have to add some tests that
@@ -81,38 +77,6 @@ func New() *Generator {
return g
}
-// NewFromTemplate creates a new Generator with the initial template being
-// unmarshaled from JSON read from the provided reader (which must unmarshal
-// into a valid ispec.Image).
-func NewFromTemplate(r io.Reader) (*Generator, error) {
- var image ispec.Image
- if err := json.NewDecoder(r).Decode(&image); err != nil {
- return nil, errors.Wrap(err, "decode image")
- }
-
- // TODO: Should we validate the image here?
-
- g := &Generator{
- image: image,
- }
-
- g.init()
- return g, nil
-}
-
-// NewFromFile creates a new Generator with the initial template being
-// unmarshaled from JSON read from the provided file (which must unmarshal
-// into a valid ispec.Image).
-func NewFromFile(path string) (*Generator, error) {
- fh, err := os.Open(path)
- if err != nil {
- return nil, errors.Wrap(err, "open image data")
- }
- defer fh.Close()
-
- return NewFromTemplate(fh)
-}
-
// NewFromImage generates a new generator with the initial template being the
// given ispec.Image.
func NewFromImage(image ispec.Image) (*Generator, error) {
@@ -194,7 +158,11 @@ func (g *Generator) ConfigEnv() []string {
// SetConfigEntrypoint sets the list of arguments to use as the command to execute when the container starts.
func (g *Generator) SetConfigEntrypoint(entrypoint []string) {
- g.image.Config.Entrypoint = entrypoint
+ copy := []string{}
+ for _, v := range entrypoint {
+ copy = append(copy, v)
+ }
+ g.image.Config.Entrypoint = copy
}
// ConfigEntrypoint returns the list of arguments to use as the command to execute when the container starts.
@@ -208,8 +176,12 @@ func (g *Generator) ConfigEntrypoint() []string {
}
// SetConfigCmd sets the list of default arguments to the entrypoint of the container.
-func (g *Generator) SetConfigCmd(entrypoint []string) {
- g.image.Config.Cmd = entrypoint
+func (g *Generator) SetConfigCmd(cmd []string) {
+ copy := []string{}
+ for _, v := range cmd {
+ copy = append(copy, v)
+ }
+ g.image.Config.Cmd = copy
}
// ConfigCmd returns the list of default arguments to the entrypoint of the container.
Oops, something went wrong.

0 comments on commit 830921c

Please sign in to comment.