...

Source file src/go.etcd.io/etcd/server/v3/mvcc/backend/verify_test.go

Documentation: go.etcd.io/etcd/server/v3/mvcc/backend

     1  // Copyright 2022 The etcd 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 backend_test
    16  
    17  import (
    18  	"os"
    19  	"testing"
    20  	"time"
    21  
    22  	"go.etcd.io/etcd/server/v3/mvcc/backend"
    23  	betesting "go.etcd.io/etcd/server/v3/mvcc/backend/testing"
    24  )
    25  
    26  func TestLockVerify(t *testing.T) {
    27  	tcs := []struct {
    28  		name                      string
    29  		insideApply               bool
    30  		lock                      func(tx backend.BatchTx)
    31  		txPostLockInsideApplyHook func()
    32  		expectPanic               bool
    33  	}{
    34  		{
    35  			name:        "call lockInsideApply from inside apply",
    36  			insideApply: true,
    37  			lock:        lockInsideApply,
    38  			expectPanic: false,
    39  		},
    40  		{
    41  			name:        "call lockInsideApply from outside apply (without txPostLockInsideApplyHook)",
    42  			insideApply: false,
    43  			lock:        lockInsideApply,
    44  			expectPanic: false,
    45  		},
    46  		{
    47  			name:                      "call lockInsideApply from outside apply (with txPostLockInsideApplyHook)",
    48  			insideApply:               false,
    49  			lock:                      lockInsideApply,
    50  			txPostLockInsideApplyHook: func() {},
    51  			expectPanic:               true,
    52  		},
    53  		{
    54  			name:        "call lockOutsideApply from outside apply",
    55  			insideApply: false,
    56  			lock:        lockOutsideApply,
    57  			expectPanic: false,
    58  		},
    59  		{
    60  			name:        "call lockOutsideApply from inside apply",
    61  			insideApply: true,
    62  			lock:        lockOutsideApply,
    63  			expectPanic: true,
    64  		},
    65  		{
    66  			name:        "call Lock from unit test",
    67  			insideApply: false,
    68  			lock:        lockFromUT,
    69  			expectPanic: false,
    70  		},
    71  	}
    72  	env := os.Getenv("ETCD_VERIFY")
    73  	os.Setenv("ETCD_VERIFY", "lock")
    74  	defer func() {
    75  		os.Setenv("ETCD_VERIFY", env)
    76  	}()
    77  	for _, tc := range tcs {
    78  		t.Run(tc.name, func(t *testing.T) {
    79  
    80  			be, _ := betesting.NewTmpBackend(t, time.Hour, 10000)
    81  			be.SetTxPostLockInsideApplyHook(tc.txPostLockInsideApplyHook)
    82  
    83  			hasPaniced := handlePanic(func() {
    84  				if tc.insideApply {
    85  					applyEntries(be, tc.lock)
    86  				} else {
    87  					tc.lock(be.BatchTx())
    88  				}
    89  			}) != nil
    90  			if hasPaniced != tc.expectPanic {
    91  				t.Errorf("%v != %v", hasPaniced, tc.expectPanic)
    92  			}
    93  		})
    94  	}
    95  }
    96  
    97  func handlePanic(f func()) (result interface{}) {
    98  	defer func() {
    99  		result = recover()
   100  	}()
   101  	f()
   102  	return result
   103  }
   104  
   105  func applyEntries(be backend.Backend, f func(tx backend.BatchTx)) {
   106  	f(be.BatchTx())
   107  }
   108  
   109  func lockInsideApply(tx backend.BatchTx)  { tx.LockInsideApply() }
   110  func lockOutsideApply(tx backend.BatchTx) { tx.LockOutsideApply() }
   111  func lockFromUT(tx backend.BatchTx)       { tx.Lock() }
   112  

View as plain text