Skip to content

Commit e0c7660

Browse files
committed
add tests
Signed-off-by: Mikhail Scherba <mikhail.scherba@flant.com>
1 parent 7c41891 commit e0c7660

File tree

4 files changed

+240
-14
lines changed

4 files changed

+240
-14
lines changed

pkg/module_manager/environment_manager/evironment_manager.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const (
3131
ShellHookEnvironment
3232
)
3333

34+
const testsEnv = "ADDON_OPERATOR_IS_TESTS_ENVIRONMENT"
35+
3436
type ObjectDescriptor struct {
3537
Source string
3638
Target string
@@ -76,7 +78,7 @@ func (m *Manager) DisassembleEnvironmentForModule(moduleName, modulePath string,
7678
defer m.l.Unlock()
7779

7880
currentEnvironment := m.preparedEnvironments[moduleName]
79-
if currentEnvironment == NoEnvironment {
81+
if currentEnvironment == NoEnvironment || currentEnvironment == targetEnvironment {
8082
return nil
8183
}
8284

@@ -87,7 +89,7 @@ func (m *Manager) DisassembleEnvironmentForModule(moduleName, modulePath string,
8789

8890
chrootedModuleEnvPath := filepath.Join(m.chroot, moduleName)
8991
for _, properties := range m.objects {
90-
if targetEnvironment != currentEnvironment && properties.TargetEnvironment > targetEnvironment {
92+
if properties.TargetEnvironment > targetEnvironment && currentEnvironment == properties.TargetEnvironment {
9193
var chrootedObjectPath string
9294
if len(properties.Target) > 0 {
9395
chrootedObjectPath = filepath.Join(chrootedModuleEnvPath, properties.Target)
@@ -110,9 +112,11 @@ func (m *Manager) DisassembleEnvironmentForModule(moduleName, modulePath string,
110112
}
111113

112114
if targetEnvironment == NoEnvironment {
113-
chrootedModuleDir := filepath.Join(chrootedModuleEnvPath, modulePath)
114-
if err := syscall.Unmount(chrootedModuleDir, 0); err != nil {
115-
return fmt.Errorf("unmount %q module's dir: %w", modulePath, err)
115+
if os.Getenv(testsEnv) != "true" {
116+
chrootedModuleDir := filepath.Join(chrootedModuleEnvPath, modulePath)
117+
if err := syscall.Unmount(chrootedModuleDir, 0); err != nil {
118+
return fmt.Errorf("unmount %q module's dir: %w", modulePath, err)
119+
}
116120
}
117121

118122
delete(m.preparedEnvironments, moduleName)
@@ -154,8 +158,10 @@ func (m *Manager) AssembleEnvironmentForModule(moduleName, modulePath string, ta
154158
return fmt.Errorf("make %q module's dir: %w", modulePath, err)
155159
}
156160

157-
if err := syscall.Mount(modulePath, chrootedModuleDir, "", syscall.MS_BIND|syscall.MS_RDONLY, ""); err != nil {
158-
return fmt.Errorf("mount %q module's dir: %w", modulePath, err)
161+
if os.Getenv(testsEnv) != "true" {
162+
if err := syscall.Mount(modulePath, chrootedModuleDir, "", syscall.MS_BIND|syscall.MS_RDONLY, ""); err != nil {
163+
return fmt.Errorf("mount %q module's dir: %w", modulePath, err)
164+
}
159165
}
160166
}
161167

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
package environment_manager
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/deckhouse/deckhouse/pkg/log"
10+
"github.com/gofrs/uuid/v5"
11+
"github.com/stretchr/testify/assert"
12+
//"github.com/stretchr/testify/assert"
13+
)
14+
15+
const (
16+
enabledScriptFile1 = "./testdata/enabledScriptFile1"
17+
enabledScriptFile2 = "./testdata/enabledScriptFile2"
18+
dstEnabledScriptFile2 = "/path/to/enabledScriptFile2"
19+
shellHookFile1 = "./testdata/shellHookFile1"
20+
shellHookFile2 = "./testdata/shellHookFile2"
21+
dstShellHookFile2 = "/path/to/shellHookFile2"
22+
chrootDir = "./testdata/chroot"
23+
24+
moduleName = "foo-bar"
25+
modulePath = "./testdata/original/module/foo-bar"
26+
)
27+
28+
func TestEnvironmentManager(t *testing.T) {
29+
os.Setenv(testsEnv, "true")
30+
31+
m, uuids, err := prepareTestData()
32+
assert.NoError(t, err)
33+
assert.Len(t, m.preparedEnvironments, 0)
34+
assert.Equal(t, NoEnvironment, m.preparedEnvironments[moduleName])
35+
36+
// prepare enabled script environment
37+
err = m.AssembleEnvironmentForModule(moduleName, modulePath, EnabledScriptEnvironment)
38+
assert.NoError(t, err)
39+
assert.Len(t, m.preparedEnvironments, 1)
40+
assert.Equal(t, EnabledScriptEnvironment, m.preparedEnvironments[moduleName])
41+
42+
// check idempotency
43+
err = m.AssembleEnvironmentForModule(moduleName, modulePath, EnabledScriptEnvironment)
44+
assert.NoError(t, err)
45+
assert.Len(t, m.preparedEnvironments, 1)
46+
assert.Equal(t, EnabledScriptEnvironment, m.preparedEnvironments[moduleName])
47+
48+
chrootedModuleEnvPath := filepath.Join(m.chroot, moduleName)
49+
50+
// check if the module's dir is created
51+
info, err := os.Stat(chrootedModuleEnvPath)
52+
assert.NoError(t, err)
53+
assert.True(t, info.IsDir(), "the module's original directory must be created in the chrooted environment")
54+
55+
// check enabled script file 1 is copied
56+
bytesRead, err := os.ReadFile(filepath.Join(chrootedModuleEnvPath, enabledScriptFile1))
57+
assert.NoError(t, err)
58+
assert.Equal(t, uuids[enabledScriptFile1], string(bytesRead))
59+
60+
// check enabled script file 2 is copied
61+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, dstEnabledScriptFile2))
62+
assert.NoError(t, err)
63+
assert.Equal(t, uuids[enabledScriptFile2], string(bytesRead))
64+
65+
// check shell hook files 1 and 2 don't exist
66+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, shellHookFile1))
67+
assert.True(t, os.IsNotExist(err), "shell hook file 1 mustn't exist")
68+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, dstShellHookFile2))
69+
assert.True(t, os.IsNotExist(err), "shell hook file 2 mustn't exist")
70+
71+
// promote to shell hook environment
72+
err = m.AssembleEnvironmentForModule(moduleName, modulePath, ShellHookEnvironment)
73+
assert.NoError(t, err)
74+
assert.Len(t, m.preparedEnvironments, 1)
75+
assert.Equal(t, ShellHookEnvironment, m.preparedEnvironments[moduleName])
76+
77+
// check enabled script file 1 is in place
78+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, enabledScriptFile1))
79+
assert.NoError(t, err)
80+
assert.Equal(t, uuids[enabledScriptFile1], string(bytesRead))
81+
82+
// check enabled script file 2 is in place
83+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, dstEnabledScriptFile2))
84+
assert.NoError(t, err)
85+
assert.Equal(t, uuids[enabledScriptFile2], string(bytesRead))
86+
87+
// check shell hook file 1 is in place
88+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, shellHookFile1))
89+
assert.NoError(t, err)
90+
assert.Equal(t, uuids[shellHookFile1], string(bytesRead))
91+
92+
// check shell hook file 2 is in place
93+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, dstShellHookFile2))
94+
assert.NoError(t, err)
95+
assert.Equal(t, uuids[shellHookFile2], string(bytesRead))
96+
97+
// demote to enabled script environment
98+
err = m.DisassembleEnvironmentForModule(moduleName, modulePath, EnabledScriptEnvironment)
99+
assert.NoError(t, err)
100+
assert.Len(t, m.preparedEnvironments, 1)
101+
assert.Equal(t, EnabledScriptEnvironment, m.preparedEnvironments[moduleName])
102+
103+
// check enabled script file 1 is in place
104+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, enabledScriptFile1))
105+
assert.NoError(t, err)
106+
assert.Equal(t, uuids[enabledScriptFile1], string(bytesRead))
107+
108+
// check enabled script file 2 is in place
109+
bytesRead, err = os.ReadFile(filepath.Join(chrootedModuleEnvPath, dstEnabledScriptFile2))
110+
assert.NoError(t, err)
111+
assert.Equal(t, uuids[enabledScriptFile2], string(bytesRead))
112+
113+
// check shell hook files 1 and 2 don't exist
114+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, shellHookFile1))
115+
assert.True(t, os.IsNotExist(err), "shell hook file 1 mustn't exist")
116+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, dstShellHookFile2))
117+
assert.True(t, os.IsNotExist(err), "shell hook file 2 mustn't exist")
118+
119+
// disassemble the environment
120+
err = m.DisassembleEnvironmentForModule(moduleName, modulePath, NoEnvironment)
121+
assert.NoError(t, err)
122+
assert.Len(t, m.preparedEnvironments, 0)
123+
assert.Equal(t, NoEnvironment, m.preparedEnvironments[moduleName])
124+
125+
// check enabled script files 1 and 2 don't exist
126+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, enabledScriptFile1))
127+
assert.True(t, os.IsNotExist(err), "enabled script file 1 mustn't exist")
128+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, dstEnabledScriptFile2))
129+
assert.True(t, os.IsNotExist(err), "enabled script file 2 mustn't exist")
130+
131+
// check shell hook files 1 and 2 don't exist
132+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, shellHookFile1))
133+
assert.True(t, os.IsNotExist(err), "shell hook file 1 mustn't exist")
134+
_, err = os.Stat(filepath.Join(chrootedModuleEnvPath, dstShellHookFile2))
135+
assert.True(t, os.IsNotExist(err), "shell hook file 2 mustn't exist")
136+
137+
// check idempotency
138+
err = m.DisassembleEnvironmentForModule(moduleName, modulePath, NoEnvironment)
139+
assert.NoError(t, err)
140+
assert.Len(t, m.preparedEnvironments, 0)
141+
assert.Equal(t, NoEnvironment, m.preparedEnvironments[moduleName])
142+
143+
err = cleanupTestData()
144+
assert.NoError(t, err)
145+
}
146+
147+
func prepareTestData() (*Manager, map[string]string, error) {
148+
uuids := map[string]string{
149+
enabledScriptFile1: "",
150+
enabledScriptFile2: "",
151+
shellHookFile1: "",
152+
shellHookFile2: "",
153+
}
154+
155+
for file := range uuids {
156+
uuid, err := uuid.NewV4()
157+
if err != nil {
158+
return nil, nil, fmt.Errorf("generate uuid: %w", err)
159+
}
160+
161+
uuids[file] = uuid.String()
162+
if err = os.WriteFile(file, []byte(uuid.String()), 0644); err != nil {
163+
return nil, nil, fmt.Errorf("write uuid to file %s: %w", file, err)
164+
}
165+
166+
}
167+
168+
m := NewManager(chrootDir, log.NewNop())
169+
m.AddObjectsToEnvironment([]ObjectDescriptor{
170+
{
171+
Source: enabledScriptFile1,
172+
Type: File,
173+
TargetEnvironment: EnabledScriptEnvironment,
174+
},
175+
{
176+
Source: enabledScriptFile2,
177+
Type: File,
178+
Target: dstEnabledScriptFile2,
179+
TargetEnvironment: EnabledScriptEnvironment,
180+
},
181+
{
182+
Source: shellHookFile1,
183+
Type: File,
184+
TargetEnvironment: ShellHookEnvironment,
185+
},
186+
{
187+
Source: shellHookFile2,
188+
Type: File,
189+
Target: dstShellHookFile2,
190+
TargetEnvironment: ShellHookEnvironment,
191+
},
192+
}...)
193+
194+
return m, uuids, nil
195+
}
196+
197+
func cleanupTestData() error {
198+
err := os.Remove(enabledScriptFile1)
199+
if err != nil {
200+
return fmt.Errorf("delete testdata file %s: %w", enabledScriptFile1, err)
201+
}
202+
203+
err = os.Remove(enabledScriptFile2)
204+
if err != nil {
205+
return fmt.Errorf("delete testdata file %s: %w", enabledScriptFile2, err)
206+
}
207+
208+
err = os.Remove(shellHookFile1)
209+
if err != nil {
210+
return fmt.Errorf("delete testdata file %s: %w", shellHookFile1, err)
211+
}
212+
213+
err = os.Remove(shellHookFile2)
214+
if err != nil {
215+
return fmt.Errorf("delete testdata file %s: %w", shellHookFile2, err)
216+
}
217+
218+
err = os.RemoveAll(chrootDir)
219+
if err != nil {
220+
return fmt.Errorf("delete chroot dir %s: %w", chrootDir, err)
221+
}
222+
223+
return nil
224+
}

pkg/module_manager/models/hooks/kind/shellhook.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package kind
22

33
import (
4-
"bytes"
54
"fmt"
65
"log/slog"
76
"os"
@@ -180,7 +179,6 @@ func (sh *ShellHook) getConfig() ([]byte, error) {
180179
envs := make([]string, 0)
181180
envs = append(envs, os.Environ()...)
182181
args := []string{"--config"}
183-
var stderrBuf bytes.Buffer
184182

185183
cmd := executor.NewExecutor(
186184
"",
@@ -191,7 +189,6 @@ func (sh *ShellHook) getConfig() ([]byte, error) {
191189
WithLogProxyHookJSONKey(sh.LogProxyHookJSONKey).
192190
WithLogger(sh.Logger.Named("executor")).
193191
WithCMDStdout(nil).
194-
WithCMDStderr(&stderrBuf).
195192
WithChroot(utils.GetModuleChrootPath(sh.moduleName))
196193

197194
sh.Hook.Logger.Debug("Executing hook",
@@ -202,8 +199,7 @@ func (sh *ShellHook) getConfig() ([]byte, error) {
202199
sh.Hook.Logger.Debug("Hook config failed",
203200
slog.String("hook", sh.Name),
204201
log.Err(err),
205-
slog.String("output", string(output)),
206-
slog.String("stderr", stderrBuf.String()))
202+
slog.String("output", string(output)))
207203
return nil, err
208204
}
209205

pkg/module_manager/module_manager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ func NewModuleManager(ctx context.Context, cfg *ModuleManagerConfig, logger *log
177177
return mm
178178
}
179179

180-
// SetRequiredObjects sets the list of objects to implement in the chroot directory
181-
func (mm *ModuleManager) SetRequiredObjects(objects ...environmentmanager.ObjectDescriptor) {
180+
// AddObjectsToChrootEnvironment sets the list of objects to implement in the modules' chroot directories
181+
func (mm *ModuleManager) AddObjectsToChrootEnvironment(objects ...environmentmanager.ObjectDescriptor) {
182182
if mm.EnvironmentManagerEnabled() {
183183
mm.environmentManager.AddObjectsToEnvironment(objects...)
184184
}

0 commit comments

Comments
 (0)