summaryrefslogtreecommitdiff
path: root/pkg/hooks/monitor_test.go
blob: 9cbde19867e105cfac0bb21680a2a2eade37ec06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package hooks

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
	"time"

	rspec "github.com/opencontainers/runtime-spec/specs-go"
	"github.com/stretchr/testify/assert"
)

func TestMonitorGood(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	dir, err := ioutil.TempDir("", "hooks-test-")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	manager, err := New(ctx, []string{dir})
	if err != nil {
		t.Fatal(err)
	}

	sync := make(chan error, 2)
	go manager.Monitor(ctx, sync)
	err = <-sync
	if err != nil {
		t.Fatal(err)
	}

	jsonPath := filepath.Join(dir, "a.json")

	t.Run("good-addition", func(t *testing.T) {
		err = ioutil.WriteFile(jsonPath, []byte(fmt.Sprintf("{\"version\": \"1.0.0\", \"hook\": {\"path\": \"%s\"}, \"when\": {\"always\": true}, \"stages\": [\"prestart\", \"poststart\", \"poststop\"]}", path)), 0644)
		if err != nil {
			t.Fatal(err)
		}

		time.Sleep(100 * time.Millisecond) // wait for monitor to notice

		config := &rspec.Spec{}
		err = manager.Hooks(config, map[string]string{}, false)
		if err != nil {
			t.Fatal(err)
		}

		assert.Equal(t, &rspec.Hooks{
			Prestart: []rspec.Hook{
				{
					Path: path,
				},
			},
			Poststart: []rspec.Hook{
				{
					Path: path,
				},
			},
			Poststop: []rspec.Hook{
				{
					Path: path,
				},
			},
		}, config.Hooks)
	})

	t.Run("good-removal", func(t *testing.T) {
		err = os.Remove(jsonPath)
		if err != nil {
			t.Fatal(err)
		}

		time.Sleep(100 * time.Millisecond) // wait for monitor to notice

		config := &rspec.Spec{}
		expected := config.Hooks
		err = manager.Hooks(config, map[string]string{}, false)
		if err != nil {
			t.Fatal(err)
		}
		assert.Equal(t, expected, config.Hooks)
	})

	t.Run("bad-addition", func(t *testing.T) {
		err = ioutil.WriteFile(jsonPath, []byte("{\"version\": \"-1\"]}"), 0644)
		if err != nil {
			t.Fatal(err)
		}

		time.Sleep(100 * time.Millisecond) // wait for monitor to notice

		config := &rspec.Spec{}
		expected := config.Hooks
		err = manager.Hooks(config, map[string]string{}, false)
		if err != nil {
			t.Fatal(err)
		}
		assert.Equal(t, expected, config.Hooks)

		err = os.Remove(jsonPath)
		if err != nil {
			t.Fatal(err)
		}
	})

	cancel()
	err = <-sync
	assert.Equal(t, context.Canceled, err)
}

func TestMonitorBadWatcher(t *testing.T) {
	ctx := context.Background()
	manager, err := New(ctx, []string{})
	if err != nil {
		t.Fatal(err)
	}
	manager.directories = []string{"/does/not/exist"}

	sync := make(chan error, 2)
	go manager.Monitor(ctx, sync)
	err = <-sync
	if !os.IsNotExist(err) {
		t.Fatal("opaque wrapping for not-exist errors")
	}
}