...

Source file src/k8s.io/utils/keymutex/keymutex_test.go

Documentation: k8s.io/utils/keymutex

     1  /*
     2  Copyright 2015 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package keymutex
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  )
    23  
    24  const (
    25  	callbackTimeout = 1 * time.Second
    26  )
    27  
    28  func newKeyMutexes() []KeyMutex {
    29  	return []KeyMutex{
    30  		NewHashed(0),
    31  		NewHashed(1),
    32  		NewHashed(2),
    33  		NewHashed(4),
    34  	}
    35  }
    36  
    37  func Test_SingleLock_NoUnlock(t *testing.T) {
    38  	for _, km := range newKeyMutexes() {
    39  		// Arrange
    40  		key := "fakeid"
    41  		callbackCh := make(chan interface{})
    42  
    43  		// Act
    44  		go lockAndCallback(km, key, callbackCh)
    45  
    46  		// Assert
    47  		verifyCallbackHappens(t, callbackCh)
    48  	}
    49  }
    50  
    51  func Test_SingleLock_SingleUnlock(t *testing.T) {
    52  	for _, km := range newKeyMutexes() {
    53  		// Arrange
    54  		key := "fakeid"
    55  		callbackCh := make(chan interface{})
    56  
    57  		// Act & Assert
    58  		go lockAndCallback(km, key, callbackCh)
    59  		verifyCallbackHappens(t, callbackCh)
    60  		km.UnlockKey(key)
    61  	}
    62  }
    63  
    64  func Test_DoubleLock_DoubleUnlock(t *testing.T) {
    65  	for _, km := range newKeyMutexes() {
    66  		// Arrange
    67  		key := "fakeid"
    68  		callbackCh1stLock := make(chan interface{})
    69  		callbackCh2ndLock := make(chan interface{})
    70  
    71  		// Act & Assert
    72  		go lockAndCallback(km, key, callbackCh1stLock)
    73  		verifyCallbackHappens(t, callbackCh1stLock)
    74  		go lockAndCallback(km, key, callbackCh2ndLock)
    75  		verifyCallbackDoesntHappens(t, callbackCh2ndLock)
    76  		km.UnlockKey(key)
    77  		verifyCallbackHappens(t, callbackCh2ndLock)
    78  		km.UnlockKey(key)
    79  	}
    80  }
    81  
    82  func lockAndCallback(km KeyMutex, id string, callbackCh chan<- interface{}) {
    83  	km.LockKey(id)
    84  	callbackCh <- true
    85  }
    86  
    87  func verifyCallbackHappens(t *testing.T, callbackCh <-chan interface{}) bool {
    88  	select {
    89  	case <-callbackCh:
    90  		return true
    91  	case <-time.After(callbackTimeout):
    92  		t.Fatalf("Timed out waiting for callback.")
    93  		return false
    94  	}
    95  }
    96  
    97  func verifyCallbackDoesntHappens(t *testing.T, callbackCh <-chan interface{}) bool {
    98  	select {
    99  	case <-callbackCh:
   100  		t.Fatalf("Unexpected callback.")
   101  		return false
   102  	case <-time.After(callbackTimeout):
   103  		return true
   104  	}
   105  }
   106  

View as plain text