...

Source file src/k8s.io/utils/inotify/inotify_linux_test.go

Documentation: k8s.io/utils/inotify

     1  //go:build linux
     2  // +build linux
     3  
     4  // Copyright 2010 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  package inotify
     9  
    10  import (
    11  	"io/ioutil"
    12  	"os"
    13  	"sync/atomic"
    14  	"testing"
    15  	"time"
    16  )
    17  
    18  func TestInotifyEvents(t *testing.T) {
    19  	// Create an inotify watcher instance and initialize it
    20  	watcher, err := NewWatcher()
    21  	if err != nil {
    22  		t.Fatalf("NewWatcher failed: %s", err)
    23  	}
    24  
    25  	dir, err := ioutil.TempDir("", "inotify")
    26  	if err != nil {
    27  		t.Fatalf("TempDir failed: %s", err)
    28  	}
    29  	defer os.RemoveAll(dir)
    30  
    31  	// Add a watch for "_test"
    32  	err = watcher.Watch(dir)
    33  	if err != nil {
    34  		t.Fatalf("Watch failed: %s", err)
    35  	}
    36  
    37  	// Receive errors on the error channel on a separate goroutine
    38  	go func() {
    39  		for err := range watcher.Error {
    40  			t.Errorf("error received: %s", err)
    41  		}
    42  	}()
    43  
    44  	testFile := dir + "/TestInotifyEvents.testfile"
    45  
    46  	// Receive events on the event channel on a separate goroutine
    47  	eventstream := watcher.Event
    48  	var eventsReceived int32
    49  	done := make(chan bool)
    50  	go func() {
    51  		for event := range eventstream {
    52  			// Only count relevant events
    53  			if event.Name == testFile {
    54  				atomic.AddInt32(&eventsReceived, 1)
    55  				t.Logf("event received: %s", event)
    56  			} else {
    57  				t.Logf("unexpected event received: %s", event)
    58  			}
    59  		}
    60  		done <- true
    61  	}()
    62  
    63  	// Create a file
    64  	// This should add at least one event to the inotify event queue
    65  	_, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666)
    66  	if err != nil {
    67  		t.Fatalf("creating test file: %s", err)
    68  	}
    69  
    70  	// We expect this event to be received almost immediately, but let's wait 1 s to be sure
    71  	time.Sleep(1 * time.Second)
    72  	if atomic.AddInt32(&eventsReceived, 0) == 0 {
    73  		t.Fatal("inotify event hasn't been received after 1 second")
    74  	}
    75  
    76  	// Try closing the inotify instance
    77  	t.Log("calling Close()")
    78  	watcher.Close()
    79  	t.Log("waiting for the event channel to become closed...")
    80  	select {
    81  	case <-done:
    82  		t.Log("event channel closed")
    83  	case <-time.After(1 * time.Second):
    84  		t.Fatal("event stream was not closed after 1 second")
    85  	}
    86  }
    87  
    88  func TestInotifyClose(t *testing.T) {
    89  	watcher, _ := NewWatcher()
    90  	watcher.Close()
    91  
    92  	done := make(chan bool)
    93  	go func() {
    94  		watcher.Close()
    95  		done <- true
    96  	}()
    97  
    98  	select {
    99  	case <-done:
   100  	case <-time.After(50 * time.Millisecond):
   101  		t.Fatal("double Close() test failed: second Close() call didn't return")
   102  	}
   103  
   104  	err := watcher.Watch(os.TempDir())
   105  	if err == nil {
   106  		t.Fatal("expected error on Watch() after Close(), got nil")
   107  	}
   108  }
   109  

View as plain text