Files
podman/pkg/hooks/hooks_test.go
W. Trevor King 89430ffe65 hooks: Order injection by collated JSON filename
We also considered ordering with sort.Strings, but Matthew rejected
that because it uses a byte-by-byte UTF-8 comparison [1] which would
fail many language-specific conventions [2].

There's some more discussion of the localeToLanguage mapping in [3].
Currently language.Parse does not handle either 'C' or 'POSIX',
returning:

  und, language: tag is not well-formed

for both.

[1]: https://github.com/projectatomic/libpod/pull/686#issuecomment-387914358
[2]: https://en.wikipedia.org/wiki/Alphabetical_order#Language-specific_conventions
[3]: https://github.com/golang/go/issues/25340

Signed-off-by: W. Trevor King <wking@tremily.us>

Closes: #686
Approved by: mheon
2018-05-11 16:26:35 +00:00

179 lines
3.5 KiB
Go

package hooks
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"testing"
rspec "github.com/opencontainers/runtime-spec/specs-go"
current "github.com/projectatomic/libpod/pkg/hooks/1.0.0"
"github.com/stretchr/testify/assert"
"golang.org/x/text/language"
)
// path is the path to an example hook executable.
var path string
func TestGoodNew(t *testing.T) {
ctx := context.Background()
dir, err := ioutil.TempDir("", "hooks-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
for i, name := range []string{
"01-my-hook.json",
"01-UPPERCASE.json",
"02-another-hook.json",
} {
jsonPath := filepath.Join(dir, name)
var extraStages string
if i == 0 {
extraStages = ", \"poststart\", \"poststop\""
}
err = ioutil.WriteFile(jsonPath, []byte(fmt.Sprintf("{\"version\": \"1.0.0\", \"hook\": {\"path\": \"%s\", \"timeout\": %d}, \"when\": {\"always\": true}, \"stages\": [\"prestart\"%s]}", path, i+1, extraStages)), 0644)
if err != nil {
t.Fatal(err)
}
}
lang, err := language.Parse("und-u-va-posix")
if err != nil {
t.Fatal(err)
}
manager, err := New(ctx, []string{dir}, lang)
if err != nil {
t.Fatal(err)
}
config := &rspec.Spec{}
err = manager.Hooks(config, map[string]string{}, false)
if err != nil {
t.Fatal(err)
}
one := 1
two := 2
three := 3
assert.Equal(t, &rspec.Hooks{
Prestart: []rspec.Hook{
{
Path: path,
Timeout: &one,
},
{
Path: path,
Timeout: &two,
},
{
Path: path,
Timeout: &three,
},
},
Poststart: []rspec.Hook{
{
Path: path,
Timeout: &one,
},
},
Poststop: []rspec.Hook{
{
Path: path,
Timeout: &one,
},
},
}, config.Hooks)
}
func TestBadNew(t *testing.T) {
ctx := context.Background()
dir, err := ioutil.TempDir("", "hooks-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
jsonPath := filepath.Join(dir, "a.json")
err = ioutil.WriteFile(jsonPath, []byte("{\"version\": \"-1\"}"), 0644)
if err != nil {
t.Fatal(err)
}
lang, err := language.Parse("und-u-va-posix")
if err != nil {
t.Fatal(err)
}
_, err = New(ctx, []string{dir}, lang)
if err == nil {
t.Fatal("unexpected success")
}
assert.Regexp(t, "^parsing hook \"[^\"]*a.json\": unrecognized hook version: \"-1\"$", err.Error())
}
func TestBrokenMatch(t *testing.T) {
manager := Manager{
hooks: map[string]*current.Hook{
"a.json": {
Version: current.Version,
Hook: rspec.Hook{
Path: "/a/b/c",
},
When: current.When{
Commands: []string{"["},
},
Stages: []string{"prestart"},
},
},
}
config := &rspec.Spec{
Process: &rspec.Process{
Args: []string{"/bin/sh"},
},
}
err := manager.Hooks(config, map[string]string{}, false)
if err == nil {
t.Fatal("unexpected success")
}
assert.Regexp(t, "^matching hook \"a\\.json\": command: error parsing regexp: .*", err.Error())
}
func TestInvalidStage(t *testing.T) {
always := true
manager := Manager{
hooks: map[string]*current.Hook{
"a.json": {
Version: current.Version,
Hook: rspec.Hook{
Path: "/a/b/c",
},
When: current.When{
Always: &always,
},
Stages: []string{"does-not-exist"},
},
},
}
err := manager.Hooks(&rspec.Spec{}, map[string]string{}, false)
if err == nil {
t.Fatal("unexpected success")
}
assert.Regexp(t, "^hook \"a\\.json\": unknown stage \"does-not-exist\"$", err.Error())
}
func init() {
if runtime.GOOS != "windows" {
path = "/bin/sh"
} else {
panic("we need a reliable executable path on Windows")
}
}