main 6af0a61

partition_handler_test.go RawHistoryFolder

1package handlers
2
3import (
4	"context"
5	"testing"
6
7	"github.com/bnema/archup/internal/application/commands"
8	"github.com/bnema/archup/internal/domain/disk"
9	"github.com/bnema/archup/internal/domain/ports/mocks"
10	"go.uber.org/mock/gomock"
11)
12
13func TestPartitionHandler_Handle_Success(t *testing.T) {
14	ctrl := gomock.NewController(t)
15	defer ctrl.Finish()
16
17	mockExec := mocks.NewMockCommandExecutor(ctrl)
18	mockLogger := mocks.NewMockLogger(ctrl)
19
20	mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
21	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
22	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
23	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
24	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
25	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
26	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
27
28	handler := NewPartitionHandler(mockExec, mockLogger)
29
30	cmd := commands.PartitionDiskCommand{
31		TargetDisk:         "/dev/sda",
32		RootSizeGB:         50,
33		BootSizeGB:         1,
34		EncryptionType:     disk.EncryptionTypeNone,
35		EncryptionPassword: "",
36		FilesystemType:     disk.FilesystemExt4,
37		WipeDisks:          true,
38	}
39
40	result, err := handler.Handle(context.Background(), cmd)
41
42	if err != nil {
43		t.Fatalf("expected no error, got %v", err)
44	}
45
46	if !result.Success {
47		t.Errorf("expected success, got error: %s", result.ErrorDetail)
48	}
49
50	if result.TargetDisk != "/dev/sda" {
51		t.Errorf("expected target disk /dev/sda, got %s", result.TargetDisk)
52	}
53
54	if len(result.Partitions) != 2 {
55		t.Errorf("expected 2 partitions, got %d", len(result.Partitions))
56	}
57
58	// Check boot partition
59	if len(result.Partitions) > 0 && result.Partitions[0].MountPoint != "/boot" {
60		t.Errorf("expected first partition mount point /boot, got %s", result.Partitions[0].MountPoint)
61	}
62
63	// Check root partition
64	if len(result.Partitions) > 1 && result.Partitions[1].MountPoint != "/" {
65		t.Errorf("expected second partition mount point /, got %s", result.Partitions[1].MountPoint)
66	}
67}
68
69func TestPartitionHandler_Handle_InvalidDisk(t *testing.T) {
70	ctrl := gomock.NewController(t)
71	defer ctrl.Finish()
72
73	mockExec := mocks.NewMockCommandExecutor(ctrl)
74	mockLogger := mocks.NewMockLogger(ctrl)
75
76	mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
77	mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).Times(1)
78	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
79	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
80	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
81	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
82	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
83	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
84	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
85	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
86	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
87	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
88	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
89	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
90	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
91	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
92
93	handler := NewPartitionHandler(mockExec, mockLogger)
94
95	cmd := commands.PartitionDiskCommand{
96		TargetDisk:     "",
97		RootSizeGB:     50,
98		BootSizeGB:     1,
99		EncryptionType: disk.EncryptionTypeNone,
100		FilesystemType: disk.FilesystemExt4,
101	}
102
103	result, err := handler.Handle(context.Background(), cmd)
104
105	if err == nil {
106		t.Error("expected error for invalid disk")
107	}
108
109	if result.Success {
110		t.Error("expected result to indicate failure")
111	}
112}
113
114func TestPartitionHandler_Handle_RootPartitionTooSmall(t *testing.T) {
115	ctrl := gomock.NewController(t)
116	defer ctrl.Finish()
117
118	mockExec := mocks.NewMockCommandExecutor(ctrl)
119	mockLogger := mocks.NewMockLogger(ctrl)
120
121	mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
122	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
123	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
124	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
125	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
126	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
127	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
128	mockExec.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte{}, nil).AnyTimes()
129
130	handler := NewPartitionHandler(mockExec, mockLogger)
131
132	cmd := commands.PartitionDiskCommand{
133		TargetDisk:     "/dev/sda",
134		RootSizeGB:     1, // Too small
135		BootSizeGB:     1,
136		EncryptionType: disk.EncryptionTypeNone,
137		FilesystemType: disk.FilesystemExt4,
138	}
139
140	result, err := handler.Handle(context.Background(), cmd)
141
142	if err != nil {
143		t.Fatalf("expected no error, got %v", err)
144	}
145
146	if !result.Success {
147		t.Errorf("expected success, got error: %s", result.ErrorDetail)
148	}
149}
150
151func TestPartitionHandler_SetupLUKSEncryption_UsesStdinForPassword(t *testing.T) {
152	ctrl := gomock.NewController(t)
153	defer ctrl.Finish()
154
155	mockExec := mocks.NewMockCommandExecutor(ctrl)
156	mockLogger := mocks.NewMockLogger(ctrl)
157
158	password := "pa'ss$word !"
159
160	mockLogger.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes()
161	mockExec.EXPECT().Execute(gomock.Any(), "wipefs", "-af", "/dev/sda2").Return([]byte{}, nil)
162	mockExec.EXPECT().ExecuteWithStdin(
163		gomock.Any(),
164		password,
165		"cryptsetup",
166		"luksFormat",
167		"--type", "luks2",
168		"--batch-mode",
169		"--pbkdf", "argon2id",
170		"--iter-time", "2000",
171		"--label", "ARCHUP_LUKS",
172		"--key-file=-",
173		"/dev/sda2",
174	).Return([]byte{}, nil)
175	mockExec.EXPECT().ExecuteWithStdin(
176		gomock.Any(),
177		password,
178		"cryptsetup",
179		"open",
180		"--key-file=-",
181		"/dev/sda2",
182		"cryptroot",
183	).Return([]byte{}, nil)
184
185	handler := NewPartitionHandler(mockExec, mockLogger)
186
187	cryptDevice, err := handler.setupLUKSEncryption(context.Background(), "/dev/sda2", password)
188	if err != nil {
189		t.Fatalf("expected no error, got %v", err)
190	}
191
192	if cryptDevice != "/dev/mapper/cryptroot" {
193		t.Fatalf("expected cryptroot mapper path, got %q", cryptDevice)
194	}
195}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close