gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/platform/interrupt/interrupt_test.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package interrupt
    16  
    17  import (
    18  	"testing"
    19  )
    20  
    21  type countingReceiver struct {
    22  	interrupts int
    23  }
    24  
    25  // NotifyInterrupt implements Receiver.NotifyInterrupt.
    26  func (r *countingReceiver) NotifyInterrupt() {
    27  	r.interrupts++
    28  }
    29  
    30  func TestSingleInterruptBeforeEnable(t *testing.T) {
    31  	var (
    32  		f Forwarder
    33  		r countingReceiver
    34  	)
    35  	f.NotifyInterrupt()
    36  	// The interrupt should cause the first Enable to fail.
    37  	if f.Enable(&r) {
    38  		f.Disable()
    39  		t.Fatalf("Enable: got true, wanted false")
    40  	}
    41  	// The failing Enable "acknowledges" the interrupt, allowing future Enables
    42  	// to succeed.
    43  	if !f.Enable(&r) {
    44  		t.Fatalf("Enable: got false, wanted true")
    45  	}
    46  	f.Disable()
    47  }
    48  
    49  func TestMultipleInterruptsBeforeEnable(t *testing.T) {
    50  	var (
    51  		f Forwarder
    52  		r countingReceiver
    53  	)
    54  	f.NotifyInterrupt()
    55  	f.NotifyInterrupt()
    56  	// The interrupts should cause the first Enable to fail.
    57  	if f.Enable(&r) {
    58  		f.Disable()
    59  		t.Fatalf("Enable: got true, wanted false")
    60  	}
    61  	// Interrupts are deduplicated while the Forwarder is disabled, so the
    62  	// failing Enable "acknowledges" all interrupts, allowing future Enables to
    63  	// succeed.
    64  	if !f.Enable(&r) {
    65  		t.Fatalf("Enable: got false, wanted true")
    66  	}
    67  	f.Disable()
    68  }
    69  
    70  func TestSingleInterruptAfterEnable(t *testing.T) {
    71  	var (
    72  		f Forwarder
    73  		r countingReceiver
    74  	)
    75  	if !f.Enable(&r) {
    76  		t.Fatalf("Enable: got false, wanted true")
    77  	}
    78  	defer f.Disable()
    79  	f.NotifyInterrupt()
    80  	if r.interrupts != 1 {
    81  		t.Errorf("interrupts: got %d, wanted 1", r.interrupts)
    82  	}
    83  }
    84  
    85  func TestMultipleInterruptsAfterEnable(t *testing.T) {
    86  	var (
    87  		f Forwarder
    88  		r countingReceiver
    89  	)
    90  	if !f.Enable(&r) {
    91  		t.Fatalf("Enable: got false, wanted true")
    92  	}
    93  	defer f.Disable()
    94  	f.NotifyInterrupt()
    95  	f.NotifyInterrupt()
    96  	if r.interrupts != 2 {
    97  		t.Errorf("interrupts: got %d, wanted 2", r.interrupts)
    98  	}
    99  }