@@ -3,114 +3,156 @@ package capture
33import (
44 "os"
55 "path/filepath"
6- "runtime"
76 "testing"
87
9- "yc-agent/internal/capture/executils"
10-
118 "github.com/stretchr/testify/assert"
129 "github.com/stretchr/testify/require"
1310)
1411
1512func TestVMStat_CaptureToFile (t * testing.T ) {
16- // TODO: Revisit this test - currently failing in CI
17- // Test subtests are failing: successful_primary_command, command_fails_with_non-zero_exit.
18- // May have issues with vmstat command mocking or file operations in CI environment.
19- t .Skip ("Skipping until vmstat capture tests can be fixed" )
20-
21- if runtime .GOOS != "linux" {
22- t .Skip ("Skipping test for non Linux env" )
23- }
24-
25- // Create temporary directory for test execution
26- tmpDir , err := os .MkdirTemp ("" , "vmstat-capture-test-*" )
27- require .NoError (t , err , "Failed to create temp directory" )
28- defer os .RemoveAll (tmpDir )
29-
30- // Change to temp directory for test execution
31- originalDir , err := os .Getwd ()
32- require .NoError (t , err , "Failed to get current directory" )
33- defer os .Chdir (originalDir )
34-
35- err = os .Chdir (tmpDir )
36- require .NoError (t , err , "Failed to change to temp directory" )
37-
38- tests := []struct {
39- name string
40- setupCommands func ()
41- expectedError bool
42- expectedFile bool
43- checkContents bool
44- }{
45- {
46- name : "successful primary command" ,
47- setupCommands : func () {
48- executils .VMState = []string {"echo" , "test vmstat output" }
49- },
50- expectedError : false ,
51- expectedFile : true ,
52- checkContents : true ,
53- },
54- {
55- name : "command fails with non-zero exit" ,
56- setupCommands : func () {
57- executils .VMState = []string {"false" }
58- },
59- expectedError : false ,
60- expectedFile : true ,
61- checkContents : true ,
62- },
63- {
64- name : "file creation error" ,
65- setupCommands : func () {
66- // Create a directory with the same name as output file to cause creation error
67- os .Mkdir (vmstatOutputPath , 0755 )
68- },
69- expectedError : true ,
70- expectedFile : false ,
71- checkContents : false ,
72- },
73- }
74-
75- for _ , tc := range tests {
76- t .Run (tc .name , func (t * testing.T ) {
77- // Clean up any existing output file or directory
78- os .RemoveAll (vmstatOutputPath )
79-
80- // Setup test commands
81- tc .setupCommands ()
82-
83- // Run the capture
84- v := & VMStat {}
85- file , err := v .CaptureToFile ()
86-
87- // Check error condition
88- if tc .expectedError {
89- assert .Error (t , err )
90- assert .Nil (t , file )
91- return
92- }
93-
94- // Check success condition
95- if ! tc .expectedFile {
96- assert .NoError (t , err )
97- assert .Nil (t , file )
98- return
99- }
100-
101- // Verify successful capture
102- require .NoError (t , err )
13+ t .Run ("file creation error when path is a directory" , func (t * testing.T ) {
14+ // Create temporary directory for test execution
15+ tmpDir := t .TempDir ()
16+
17+ // Change to temp directory for test execution
18+ originalDir , err := os .Getwd ()
19+ require .NoError (t , err , "Failed to get current directory" )
20+ defer os .Chdir (originalDir )
21+
22+ err = os .Chdir (tmpDir )
23+ require .NoError (t , err , "Failed to change to temp directory" )
24+
25+ // Create a directory with the same name as output file to cause creation error
26+ err = os .Mkdir (vmstatOutputPath , 0755 )
27+ require .NoError (t , err , "Failed to create blocking directory" )
28+
29+ // Run the capture - should fail because vmstat.out is a directory
30+ v := & VMStat {}
31+ file , err := v .CaptureToFile ()
32+
33+ // Should fail with file creation error
34+ assert .Error (t , err )
35+ assert .Nil (t , file )
36+ assert .Contains (t , err .Error (), "failed to create output file" )
37+ })
38+
39+ t .Run ("creates output file in correct location" , func (t * testing.T ) {
40+ // Create temporary directory for test execution
41+ tmpDir := t .TempDir ()
42+
43+ // Change to temp directory for test execution
44+ originalDir , err := os .Getwd ()
45+ require .NoError (t , err , "Failed to get current directory" )
46+ defer os .Chdir (originalDir )
47+
48+ err = os .Chdir (tmpDir )
49+ require .NoError (t , err , "Failed to change to temp directory" )
50+
51+ // Run the capture - this will run the actual vmstat command
52+ // On CI without vmstat, this may fail, but we're testing file creation
53+ v := & VMStat {}
54+ file , err := v .CaptureToFile ()
55+
56+ // The vmstat command may not be available in all environments
57+ // If it succeeds, verify the file properties
58+ if err == nil {
10359 require .NotNil (t , file )
10460 defer file .Close ()
10561
106- // Verify the output file exists and has content
107- fileInfo , err := file .Stat ()
108- require .NoError (t , err , "Failed to get file info" )
62+ // Verify correct file name
63+ assert .Equal (t , "vmstat.out" , filepath .Base (file .Name ()))
64+
65+ // Verify the file was created
66+ _ , statErr := os .Stat (vmstatOutputPath )
67+ assert .NoError (t , statErr , "Output file should exist" )
68+ }
69+ })
70+ }
10971
110- if tc .checkContents {
111- assert .Greater (t , fileInfo .Size (), int64 (0 ), "Captured file should not be empty" )
112- }
113- assert .Equal (t , "vmstat.out" , filepath .Base (file .Name ()), "Output file should be named 'vmstat.out'" )
114- })
115- }
72+ func TestValidateLinuxVMStatOutput (t * testing.T ) {
73+ t .Run ("valid vmstat output" , func (t * testing.T ) {
74+ // Simulated valid vmstat output with 2 header lines + 5 data lines
75+ validOutput := `procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
76+ r b swpd free buff cache si so bi bo in cs us sy id wa st
77+ 0 0 0 123456 78901 234567 0 0 1 2 10 20 1 1 98 0 0
78+ 0 0 0 123457 78902 234568 0 0 0 1 11 21 1 0 99 0 0
79+ 0 0 0 123458 78903 234569 0 0 0 0 12 22 0 1 99 0 0
80+ 0 0 0 123459 78904 234570 0 0 0 1 13 23 1 0 99 0 0
81+ 0 0 0 123460 78905 234571 0 0 0 0 14 24 0 0 100 0 0`
82+
83+ valid , errMsg := validateLinuxVMStatOutput (validOutput )
84+ assert .True (t , valid , "Expected valid output to pass validation" )
85+ assert .Empty (t , errMsg , "Expected no error message for valid output" )
86+ })
87+
88+ t .Run ("wrong number of lines" , func (t * testing.T ) {
89+ // Only 3 lines instead of expected 7 (2 headers + 5 data)
90+ invalidOutput := `procs -----------memory---------- ---swap--
91+ r b swpd free buff cache
92+ 0 0 0 123456 78901 234567`
93+
94+ valid , errMsg := validateLinuxVMStatOutput (invalidOutput )
95+ assert .False (t , valid , "Expected invalid output to fail validation" )
96+ assert .Contains (t , errMsg , "Expected 7 lines" )
97+ })
98+
99+ t .Run ("missing memory header" , func (t * testing.T ) {
100+ // First line doesn't contain "-memory-"
101+ invalidOutput := `procs -----------other---------- ---swap-- -----io---- -system-- ------cpu-----
102+ r b swpd free buff cache si so bi bo in cs us sy id wa st
103+ 0 0 0 123456 78901 234567 0 0 1 2 10 20 1 1 98 0 0
104+ 0 0 0 123457 78902 234568 0 0 0 1 11 21 1 0 99 0 0
105+ 0 0 0 123458 78903 234569 0 0 0 0 12 22 0 1 99 0 0
106+ 0 0 0 123459 78904 234570 0 0 0 1 13 23 1 0 99 0 0
107+ 0 0 0 123460 78905 234571 0 0 0 0 14 24 0 0 100 0 0`
108+
109+ valid , errMsg := validateLinuxVMStatOutput (invalidOutput )
110+ assert .False (t , valid , "Expected invalid output to fail validation" )
111+ assert .Contains (t , errMsg , "-memory-" )
112+ })
113+
114+ t .Run ("missing free column header" , func (t * testing.T ) {
115+ // Second line doesn't contain "free"
116+ invalidOutput := `procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
117+ r b swpd available buff cache si so bi bo in cs us sy id wa st
118+ 0 0 0 123456 78901 234567 0 0 1 2 10 20 1 1 98 0 0
119+ 0 0 0 123457 78902 234568 0 0 0 1 11 21 1 0 99 0 0
120+ 0 0 0 123458 78903 234569 0 0 0 0 12 22 0 1 99 0 0
121+ 0 0 0 123459 78904 234570 0 0 0 1 13 23 1 0 99 0 0
122+ 0 0 0 123460 78905 234571 0 0 0 0 14 24 0 0 100 0 0`
123+
124+ valid , errMsg := validateLinuxVMStatOutput (invalidOutput )
125+ assert .False (t , valid , "Expected invalid output to fail validation" )
126+ assert .Contains (t , errMsg , "free" )
127+ })
128+
129+ t .Run ("missing buff column header" , func (t * testing.T ) {
130+ // Second line doesn't contain "buff"
131+ invalidOutput := `procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
132+ r b swpd free other cache si so bi bo in cs us sy id wa st
133+ 0 0 0 123456 78901 234567 0 0 1 2 10 20 1 1 98 0 0
134+ 0 0 0 123457 78902 234568 0 0 0 1 11 21 1 0 99 0 0
135+ 0 0 0 123458 78903 234569 0 0 0 0 12 22 0 1 99 0 0
136+ 0 0 0 123459 78904 234570 0 0 0 1 13 23 1 0 99 0 0
137+ 0 0 0 123460 78905 234571 0 0 0 0 14 24 0 0 100 0 0`
138+
139+ valid , errMsg := validateLinuxVMStatOutput (invalidOutput )
140+ assert .False (t , valid , "Expected invalid output to fail validation" )
141+ assert .Contains (t , errMsg , "buff" )
142+ })
143+
144+ t .Run ("empty data line" , func (t * testing.T ) {
145+ // One of the data lines is empty
146+ invalidOutput := `procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
147+ r b swpd free buff cache si so bi bo in cs us sy id wa st
148+ 0 0 0 123456 78901 234567 0 0 1 2 10 20 1 1 98 0 0
149+
150+ 0 0 0 123458 78903 234569 0 0 0 0 12 22 0 1 99 0 0
151+ 0 0 0 123459 78904 234570 0 0 0 1 13 23 1 0 99 0 0
152+ 0 0 0 123460 78905 234571 0 0 0 0 14 24 0 0 100 0 0`
153+
154+ valid , errMsg := validateLinuxVMStatOutput (invalidOutput )
155+ assert .False (t , valid , "Expected invalid output to fail validation" )
156+ assert .Contains (t , errMsg , "empty" )
157+ })
116158}
0 commit comments