istio.io/istio@v0.0.0-20240520182934-d79c90f27776/cni/pkg/nodeagent/fakes_test.go (about)

     1  // Copyright Istio 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 nodeagent
    16  
    17  import (
    18  	"context"
    19  	"embed"
    20  	"io/fs"
    21  	"sync/atomic"
    22  	"syscall"
    23  
    24  	corev1 "k8s.io/api/core/v1"
    25  
    26  	"istio.io/istio/cni/pkg/iptables"
    27  )
    28  
    29  //go:embed testdata/cgroupns
    30  var fakeProc embed.FS
    31  
    32  type fakeZtunnel struct {
    33  	deletedPods atomic.Int32
    34  	addedPods   atomic.Int32
    35  	addError    error
    36  }
    37  
    38  func (f *fakeZtunnel) Run(ctx context.Context) {
    39  }
    40  
    41  func (f *fakeZtunnel) PodDeleted(ctx context.Context, uid string) error {
    42  	f.deletedPods.Add(1)
    43  	return nil
    44  }
    45  
    46  func (f *fakeZtunnel) PodAdded(ctx context.Context, pod *corev1.Pod, netns Netns) error {
    47  	f.addedPods.Add(1)
    48  	return f.addError
    49  }
    50  
    51  func (f *fakeZtunnel) Close() error {
    52  	return nil
    53  }
    54  
    55  // fakeNs is a mock struct for testing
    56  type fakeNs struct {
    57  	closed *atomic.Bool
    58  	fd     uintptr
    59  	inode  uint64
    60  }
    61  
    62  func newFakeNs(fd uintptr) *fakeNs {
    63  	// the fake inode is the fd! magic.
    64  	return &fakeNs{closed: &atomic.Bool{}, fd: fd, inode: uint64(fd)}
    65  }
    66  
    67  func newFakeNsInode(fd uintptr, inode uint64) *fakeNs {
    68  	return &fakeNs{closed: &atomic.Bool{}, fd: fd, inode: inode}
    69  }
    70  
    71  // Fd returns the file descriptor
    72  func (f *fakeNs) Fd() uintptr {
    73  	return f.fd
    74  }
    75  
    76  func (f *fakeNs) Inode() uint64 {
    77  	return f.inode
    78  }
    79  
    80  // Close simulates closing the file descriptor and returns nil for no error
    81  func (f *fakeNs) Close() error {
    82  	f.closed.Store(true)
    83  	return nil
    84  }
    85  
    86  func fakeFs() fs.FS {
    87  	subFs, err := fs.Sub(fakeProc, "testdata")
    88  	if err != nil {
    89  		panic(err)
    90  	}
    91  	subFs, err = fs.Sub(subFs, "cgroupns")
    92  	if err != nil {
    93  		panic(err)
    94  	}
    95  	return &fakeFsWithFakeFds{ReadDirFS: subFs.(fs.ReadDirFS)}
    96  }
    97  
    98  type fakeFsWithFakeFds struct {
    99  	fs.ReadDirFS
   100  }
   101  type fakeFileFakeFds struct {
   102  	fs.File
   103  	fd uintptr
   104  }
   105  
   106  func (f *fakeFileFakeFds) Fd() uintptr {
   107  	return f.fd
   108  }
   109  
   110  func (f *fakeFileFakeFds) Stat() (fs.FileInfo, error) {
   111  	fi, err := f.File.Stat()
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	return &fakeFileFakeFI{FileInfo: fi}, nil
   116  }
   117  
   118  type fakeFileFakeFI struct {
   119  	fs.FileInfo
   120  }
   121  
   122  func (f *fakeFileFakeFI) Sys() any {
   123  	return &syscall.Stat_t{Ino: 1}
   124  }
   125  
   126  // Open opens the named file.
   127  // When Open returns an error, it should be of type *PathError
   128  // with the Op field set to "open", the Path field set to name,
   129  // and the Err field describing the problem.
   130  //
   131  // Open should reject attempts to open names that do not satisfy
   132  // ValidPath(name), returning a *PathError with Err set to
   133  // ErrInvalid or ErrNotExist.
   134  func (ffs *fakeFsWithFakeFds) Open(name string) (fs.File, error) {
   135  	f, err := ffs.ReadDirFS.Open(name)
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	return wrapFile(f), nil
   140  }
   141  
   142  func wrapFile(f fs.File) fs.File {
   143  	return &fakeFileFakeFds{File: f, fd: 0}
   144  }
   145  
   146  type fakeIptablesDeps struct {
   147  	AddRouteErr           error
   148  	AddInpodMarkIPRuleCnt atomic.Int32
   149  	DelInpodMarkIPRuleCnt atomic.Int32
   150  	AddLoopbackRoutesCnt  atomic.Int32
   151  	DelLoopbackRoutesCnt  atomic.Int32
   152  }
   153  
   154  var _ iptables.NetlinkDependencies = &fakeIptablesDeps{}
   155  
   156  func (r *fakeIptablesDeps) AddInpodMarkIPRule(cfg *iptables.Config) error {
   157  	r.AddInpodMarkIPRuleCnt.Add(1)
   158  	return nil
   159  }
   160  
   161  func (r *fakeIptablesDeps) DelInpodMarkIPRule(cfg *iptables.Config) error {
   162  	r.DelInpodMarkIPRuleCnt.Add(1)
   163  	return nil
   164  }
   165  
   166  func (r *fakeIptablesDeps) AddLoopbackRoutes(cfg *iptables.Config) error {
   167  	r.AddLoopbackRoutesCnt.Add(1)
   168  	return r.AddRouteErr
   169  }
   170  
   171  func (r *fakeIptablesDeps) DelLoopbackRoutes(cfg *iptables.Config) error {
   172  	r.DelLoopbackRoutesCnt.Add(1)
   173  	return nil
   174  }