@@ -76,12 +76,15 @@ func fakeQEMUBinary(t *testing.T, dir string) string {
7676 return path
7777}
7878
79- // fakeVsockDevice creates a stand-in for /dev/vhost-vsock: the prerequisite
80- // check only requires the device node to exist.
81- func fakeVsockDevice (t * testing.T , dir string ) string {
79+ // fakeVsockDevice uses a harmless character device as a stand-in for
80+ // /dev/vhost-vsock. The prerequisite check verifies node type and O_RDWR
81+ // access; it deliberately does not issue vhost ioctls during diagnostics.
82+ func fakeVsockDevice (t * testing.T , _ string ) string {
8283 t .Helper ()
83- path := filepath .Join (dir , "vhost-vsock" )
84- require .NoError (t , os .WriteFile (path , nil , 0o600 ))
84+ const path = "/dev/null"
85+ info , err := os .Stat (path )
86+ require .NoError (t , err )
87+ require .Equal (t , os .ModeDevice | os .ModeCharDevice , info .Mode ().Type ())
8588 return path
8689}
8790
@@ -149,6 +152,34 @@ func TestCheckLaunchPrerequisitesFor(t *testing.T) {
149152 require .ErrorContains (t , err , "vhost_vsock" )
150153 })
151154
155+ t .Run ("regular file is not a vsock device" , func (t * testing.T ) {
156+ dir := t .TempDir ()
157+ binary := fakeQEMUBinary (t , dir )
158+ path := filepath .Join (dir , "vhost-vsock" )
159+ require .NoError (t , os .WriteFile (path , nil , 0o600 ))
160+ err := retryingETXTBSY (t , func () error {
161+ return checkLaunchPrerequisitesFor (ctx , binary , path )
162+ })
163+ require .ErrorContains (t , err , "must be a character device" )
164+ })
165+
166+ t .Run ("directory is not a vsock device" , func (t * testing.T ) {
167+ dir := t .TempDir ()
168+ binary := fakeQEMUBinary (t , dir )
169+ err := retryingETXTBSY (t , func () error {
170+ return checkLaunchPrerequisitesFor (ctx , binary , dir )
171+ })
172+ require .ErrorContains (t , err , "must be a character device" )
173+ })
174+
175+ t .Run ("inaccessible character device fails" , func (t * testing.T ) {
176+ err := validateVsockDevice ("/dev/null" , func (string , int , os.FileMode ) (* os.File , error ) {
177+ return nil , os .ErrPermission
178+ })
179+ require .ErrorContains (t , err , "not accessible read/write" )
180+ require .ErrorIs (t , err , os .ErrPermission )
181+ })
182+
152183 t .Run ("hung binary fails at the context deadline" , func (t * testing.T ) {
153184 // A wedged QEMU binary must fail the prerequisite check when its
154185 // bounded context expires instead of blocking the capability request
0 commit comments