main 6af0a61

validation_test.go RawHistoryFolder

1package disk
2
3import (
4	"testing"
5)
6
7// TestDeterminePartitionPath tests partition path determination
8func TestDeterminePartitionPath(t *testing.T) {
9	tests := []struct {
10		name            string
11		diskPath        string
12		partitionNumber int
13		expected        string
14		shouldErr       bool
15	}{
16		// SATA/SSD cases
17		{"SATA partition 1", "/dev/sda", 1, "/dev/sda1", false},
18		{"SATA partition 2", "/dev/sda", 2, "/dev/sda2", false},
19		{"SDB partition 1", "/dev/sdb", 1, "/dev/sdb1", false},
20		// NVMe cases
21		{"NVMe partition 1", "/dev/nvme0n1", 1, "/dev/nvme0n1p1", false},
22		{"NVMe partition 2", "/dev/nvme0n1", 2, "/dev/nvme0n1p2", false},
23		{"NVMe 1 partition 1", "/dev/nvme1n1", 1, "/dev/nvme1n1p1", false},
24		// MMC cases
25		{"MMC partition 1", "/dev/mmcblk0", 1, "/dev/mmcblk0p1", false},
26		{"MMC partition 2", "/dev/mmcblk0", 2, "/dev/mmcblk0p2", false},
27		// Virtio cases
28		{"Virtio partition 1", "/dev/vda", 1, "/dev/vda1", false},
29		{"Virtio partition 2", "/dev/vda", 2, "/dev/vda2", false},
30		// Error cases
31		{"empty disk path", "", 1, "", true},
32		{"partition number 0", "/dev/sda", 0, "", true},
33		{"partition number negative", "/dev/sda", -1, "", true},
34		{"partition number too large", "/dev/sda", 129, "", true},
35		{"invalid disk path", "sda", 1, "", true},
36	}
37
38	for _, tt := range tests {
39		t.Run(tt.name, func(t *testing.T) {
40			result, err := DeterminePartitionPath(tt.diskPath, tt.partitionNumber)
41
42			if (err != nil) != tt.shouldErr {
43				t.Errorf("got error %v, expected error=%v", err, tt.shouldErr)
44			}
45
46			if !tt.shouldErr && result != tt.expected {
47				t.Errorf("got %q, want %q", result, tt.expected)
48			}
49		})
50	}
51}
52
53// TestValidateDiskPath tests disk path validation
54func TestValidateDiskPath(t *testing.T) {
55	tests := []struct {
56		name      string
57		diskPath  string
58		shouldErr bool
59	}{
60		{"valid SATA", "/dev/sda", false},
61		{"valid SDB", "/dev/sdb", false},
62		{"valid NVMe", "/dev/nvme0n1", false},
63		{"valid MMC", "/dev/mmcblk0", false},
64		{"valid Virtio", "/dev/vda", false},
65		{"valid IDE", "/dev/hda", false},
66		{"empty", "", true},
67		{"no /dev/ prefix", "sda", true},
68		{"invalid prefix", "/dev/xda", true},
69		{"too long", "/dev/" + string(make([]byte, 60)), true},
70	}
71
72	for _, tt := range tests {
73		t.Run(tt.name, func(t *testing.T) {
74			err := ValidateDiskPath(tt.diskPath)
75			if (err != nil) != tt.shouldErr {
76				t.Errorf("got error %v, expected error=%v", err, tt.shouldErr)
77			}
78		})
79	}
80}
81
82// TestValidatePartitionPath tests partition path validation
83func TestValidatePartitionPath(t *testing.T) {
84	tests := []struct {
85		name          string
86		partitionPath string
87		shouldErr     bool
88	}{
89		{"valid SATA partition", "/dev/sda1", false},
90		{"valid NVMe partition", "/dev/nvme0n1p1", false},
91		{"valid MMC partition", "/dev/mmcblk0p1", false},
92		{"valid Virtio partition", "/dev/vda1", false},
93		{"empty", "", true},
94		{"no /dev/ prefix", "sda1", true},
95		{"too long", "/dev/" + string(make([]byte, 60)), true},
96	}
97
98	for _, tt := range tests {
99		t.Run(tt.name, func(t *testing.T) {
100			err := ValidatePartitionPath(tt.partitionPath)
101			if (err != nil) != tt.shouldErr {
102				t.Errorf("got error %v, expected error=%v", err, tt.shouldErr)
103			}
104		})
105	}
106}
107
108// TestIsDiskPath tests disk vs partition detection
109func TestIsDiskPath(t *testing.T) {
110	tests := []struct {
111		name     string
112		path     string
113		expected bool
114	}{
115		// Disks
116		{"SATA disk", "/dev/sda", true},
117		{"SDB disk", "/dev/sdb", true},
118		{"NVMe disk", "/dev/nvme0n1", true},
119		{"MMC disk", "/dev/mmcblk0", true},
120		{"Virtio disk", "/dev/vda", true},
121		// Partitions
122		{"SATA partition", "/dev/sda1", false},
123		{"NVMe partition", "/dev/nvme0n1p1", false},
124		{"MMC partition", "/dev/mmcblk0p1", false},
125		{"Virtio partition", "/dev/vda1", false},
126		// Edge cases
127		{"empty", "", false},
128	}
129
130	for _, tt := range tests {
131		t.Run(tt.name, func(t *testing.T) {
132			result := IsDiskPath(tt.path)
133			if result != tt.expected {
134				t.Errorf("got %v, want %v", result, tt.expected)
135			}
136		})
137	}
138}
139
140// TestExtractDiskFromPartition tests extracting disk path from partition
141func TestExtractDiskFromPartition(t *testing.T) {
142	tests := []struct {
143		name          string
144		partitionPath string
145		expected      string
146		shouldErr     bool
147	}{
148		// SATA/SSD
149		{"SATA partition 1", "/dev/sda1", "/dev/sda", false},
150		{"SATA partition 10", "/dev/sda10", "/dev/sda", false},
151		{"SDB partition 1", "/dev/sdb1", "/dev/sdb", false},
152		// NVMe
153		{"NVMe partition 1", "/dev/nvme0n1p1", "/dev/nvme0n1", false},
154		{"NVMe partition 10", "/dev/nvme0n1p10", "/dev/nvme0n1", false},
155		{"NVMe 1 partition 1", "/dev/nvme1n1p1", "/dev/nvme1n1", false},
156		// MMC
157		{"MMC partition 1", "/dev/mmcblk0p1", "/dev/mmcblk0", false},
158		{"MMC partition 10", "/dev/mmcblk0p10", "/dev/mmcblk0", false},
159		// Virtio
160		{"Virtio partition 1", "/dev/vda1", "/dev/vda", false},
161		{"Virtio partition 10", "/dev/vda10", "/dev/vda", false},
162		// Already disk paths (should return as-is)
163		{"SATA disk", "/dev/sda", "/dev/sda", false},
164		{"NVMe disk", "/dev/nvme0n1", "/dev/nvme0n1", false},
165		// Error cases
166		{"empty", "", "", true},
167	}
168
169	for _, tt := range tests {
170		t.Run(tt.name, func(t *testing.T) {
171			result, err := ExtractDiskFromPartition(tt.partitionPath)
172
173			if (err != nil) != tt.shouldErr {
174				t.Errorf("got error %v, expected error=%v", err, tt.shouldErr)
175			}
176
177			if !tt.shouldErr && result != tt.expected {
178				t.Errorf("got %q, want %q", result, tt.expected)
179			}
180		})
181	}
182}
183
184// TestDeterminePartitionPathConsistency tests consistency between DeterminePartitionPath and ExtractDiskFromPartition
185func TestDeterminePartitionPathConsistency(t *testing.T) {
186	disks := []string{
187		"/dev/sda",
188		"/dev/sdb",
189		"/dev/nvme0n1",
190		"/dev/nvme1n1",
191		"/dev/mmcblk0",
192		"/dev/vda",
193	}
194
195	for _, disk := range disks {
196		for partNum := 1; partNum <= 5; partNum++ {
197			// Determine partition path
198			partPath, err := DeterminePartitionPath(disk, partNum)
199			if err != nil {
200				t.Fatalf("DeterminePartitionPath(%q, %d) failed: %v", disk, partNum, err)
201			}
202
203			// Extract disk from partition path
204			extractedDisk, err := ExtractDiskFromPartition(partPath)
205			if err != nil {
206				t.Fatalf("ExtractDiskFromPartition(%q) failed: %v", partPath, err)
207			}
208
209			// Should match original disk
210			if extractedDisk != disk {
211				t.Errorf("Inconsistency for %q partition %d: determined %q, extracted %q",
212					disk, partNum, partPath, extractedDisk)
213			}
214		}
215	}
216}
217
218// TestValidateDiskPathErrors tests error messages
219func TestValidateDiskPathErrors(t *testing.T) {
220	tests := []struct {
221		name      string
222		diskPath  string
223		errSubstr string
224	}{
225		{"empty", "", "cannot be empty"},
226		{"no /dev/", "sda", "must start with /dev/"},
227		{"invalid type", "/dev/xda", "unrecognized disk device type"},
228	}
229
230	for _, tt := range tests {
231		t.Run(tt.name, func(t *testing.T) {
232			err := ValidateDiskPath(tt.diskPath)
233			if err == nil {
234				t.Fatal("expected error, got nil")
235			}
236			if !contains(err.Error(), tt.errSubstr) {
237				t.Errorf("error %q does not contain %q", err.Error(), tt.errSubstr)
238			}
239		})
240	}
241}
242
243// TestValidatePartitionPathErrors tests error messages
244func TestValidatePartitionPathErrors(t *testing.T) {
245	tests := []struct {
246		name          string
247		partitionPath string
248		errSubstr     string
249	}{
250		{"empty", "", "cannot be empty"},
251		{"no /dev/", "sda1", "must start with /dev/"},
252	}
253
254	for _, tt := range tests {
255		t.Run(tt.name, func(t *testing.T) {
256			err := ValidatePartitionPath(tt.partitionPath)
257			if err == nil {
258				t.Fatal("expected error, got nil")
259			}
260			if !contains(err.Error(), tt.errSubstr) {
261				t.Errorf("error %q does not contain %q", err.Error(), tt.errSubstr)
262			}
263		})
264	}
265}
266
267// TestDeterminePartitionPathErrors tests error messages
268func TestDeterminePartitionPathErrors(t *testing.T) {
269	tests := []struct {
270		name            string
271		diskPath        string
272		partitionNumber int
273		errSubstr       string
274	}{
275		{"empty disk", "", 1, "cannot be empty"},
276		{"invalid partition 0", "/dev/sda", 0, "between 1 and 128"},
277		{"invalid partition negative", "/dev/sda", -1, "between 1 and 128"},
278		{"invalid partition large", "/dev/sda", 129, "between 1 and 128"},
279		{"no /dev/ prefix", "sda", 1, "must start with /dev/"},
280	}
281
282	for _, tt := range tests {
283		t.Run(tt.name, func(t *testing.T) {
284			_, err := DeterminePartitionPath(tt.diskPath, tt.partitionNumber)
285			if err == nil {
286				t.Fatal("expected error, got nil")
287			}
288			if !contains(err.Error(), tt.errSubstr) {
289				t.Errorf("error %q does not contain %q", err.Error(), tt.errSubstr)
290			}
291		})
292	}
293}

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