github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/worker/runtime/cni_network_test.go (about) 1 package runtime_test 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 8 "github.com/pf-qiu/concourse/v6/worker/runtime" 9 "github.com/pf-qiu/concourse/v6/worker/runtime/iptables/iptablesfakes" 10 "github.com/pf-qiu/concourse/v6/worker/runtime/libcontainerd/libcontainerdfakes" 11 "github.com/pf-qiu/concourse/v6/worker/runtime/runtimefakes" 12 "github.com/opencontainers/runtime-spec/specs-go" 13 "github.com/stretchr/testify/require" 14 "github.com/stretchr/testify/suite" 15 ) 16 17 type CNINetworkSuite struct { 18 suite.Suite 19 *require.Assertions 20 21 network runtime.Network 22 cni *runtimefakes.FakeCNI 23 store *runtimefakes.FakeFileStore 24 iptables *iptablesfakes.FakeIptables 25 } 26 27 func (s *CNINetworkSuite) SetupTest() { 28 var err error 29 30 s.store = new(runtimefakes.FakeFileStore) 31 s.cni = new(runtimefakes.FakeCNI) 32 s.iptables = new(iptablesfakes.FakeIptables) 33 34 s.network, err = runtime.NewCNINetwork( 35 runtime.WithCNIFileStore(s.store), 36 runtime.WithCNIClient(s.cni), 37 runtime.WithIptables(s.iptables), 38 ) 39 s.NoError(err) 40 } 41 42 func (s *CNINetworkSuite) TestNewCNINetworkWithInvalidConfigDoesntFail() { 43 // CNI defers the actual interpretation of the network configuration to 44 // the plugins. 45 // 46 _, err := runtime.NewCNINetwork( 47 runtime.WithCNINetworkConfig(runtime.CNINetworkConfig{ 48 Subnet: "_____________", 49 }), 50 runtime.WithIptables(s.iptables), 51 ) 52 s.NoError(err) 53 } 54 55 func (s *CNINetworkSuite) TestSetupMountsEmptyHandle() { 56 _, err := s.network.SetupMounts("") 57 s.EqualError(err, "empty handle") 58 } 59 60 func (s *CNINetworkSuite) TestSetupMountsFailToCreateHosts() { 61 s.store.CreateReturnsOnCall(0, "", errors.New("create-hosts-err")) 62 63 _, err := s.network.SetupMounts("handle") 64 s.EqualError(errors.Unwrap(err), "create-hosts-err") 65 66 s.Equal(1, s.store.CreateCallCount()) 67 fname, _ := s.store.CreateArgsForCall(0) 68 69 s.Equal("handle/hosts", fname) 70 } 71 72 func (s *CNINetworkSuite) TestSetupMountsFailToCreateResolvConf() { 73 s.store.CreateReturnsOnCall(1, "", errors.New("create-resolvconf-err")) 74 75 _, err := s.network.SetupMounts("handle") 76 s.EqualError(errors.Unwrap(err), "create-resolvconf-err") 77 78 s.Equal(2, s.store.CreateCallCount()) 79 fname, _ := s.store.CreateArgsForCall(1) 80 81 s.Equal("handle/resolv.conf", fname) 82 } 83 84 func (s *CNINetworkSuite) TestSetupMountsReturnsMountpoints() { 85 s.store.CreateReturnsOnCall(0, "/tmp/handle/etc/hosts", nil) 86 s.store.CreateReturnsOnCall(1, "/tmp/handle/etc/resolv.conf", nil) 87 88 mounts, err := s.network.SetupMounts("some-handle") 89 s.NoError(err) 90 91 s.Len(mounts, 2) 92 s.Equal(mounts, []specs.Mount{ 93 { 94 Destination: "/etc/hosts", 95 Type: "bind", 96 Source: "/tmp/handle/etc/hosts", 97 Options: []string{"bind", "rw"}, 98 }, 99 { 100 Destination: "/etc/resolv.conf", 101 Type: "bind", 102 Source: "/tmp/handle/etc/resolv.conf", 103 Options: []string{"bind", "rw"}, 104 }, 105 }) 106 } 107 108 func (s *CNINetworkSuite) TestSetupMountsCallsStoreWithNameServers() { 109 network, err := runtime.NewCNINetwork( 110 runtime.WithCNIFileStore(s.store), 111 runtime.WithNameServers([]string{"6.6.7.7", "1.2.3.4"}), 112 runtime.WithIptables(s.iptables), 113 ) 114 s.NoError(err) 115 116 _, err = network.SetupMounts("some-handle") 117 s.NoError(err) 118 119 _, resolvConfContents := s.store.CreateArgsForCall(1) 120 s.Equal(resolvConfContents, []byte("nameserver 6.6.7.7\nnameserver 1.2.3.4")) 121 } 122 123 func (s *CNINetworkSuite) TestSetupMountsCallsStoreWithoutNameServers() { 124 network, err := runtime.NewCNINetwork( 125 runtime.WithCNIFileStore(s.store), 126 runtime.WithIptables(s.iptables), 127 ) 128 s.NoError(err) 129 130 _, err = network.SetupMounts("some-handle") 131 s.NoError(err) 132 133 actualResolvContents, err := runtime.ParseHostResolveConf("/etc/resolv.conf") 134 s.NoError(err) 135 136 contents := strings.Join(actualResolvContents, "\n") 137 138 _, resolvConfContents := s.store.CreateArgsForCall(1) 139 s.Equal(resolvConfContents, []byte(contents)) 140 } 141 142 func (s *CNINetworkSuite) TestSetupRestrictedNetworksCreatesEmptyAdminChain() { 143 network, err := runtime.NewCNINetwork( 144 runtime.WithRestrictedNetworks([]string{"1.1.1.1", "8.8.8.8"}), 145 runtime.WithIptables(s.iptables), 146 ) 147 148 err = network.SetupRestrictedNetworks() 149 s.NoError(err) 150 151 tablename, chainName := s.iptables.CreateChainOrFlushIfExistsArgsForCall(0) 152 s.Equal(tablename, "filter") 153 s.Equal(chainName, "CONCOURSE-OPERATOR") 154 155 tablename, chainName, rulespec := s.iptables.AppendRuleArgsForCall(0) 156 s.Equal(tablename, "filter") 157 s.Equal(chainName, "CONCOURSE-OPERATOR") 158 s.Equal(rulespec, []string{"-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"}) 159 160 tablename, chainName, rulespec = s.iptables.AppendRuleArgsForCall(1) 161 s.Equal(tablename, "filter") 162 s.Equal(chainName, "CONCOURSE-OPERATOR") 163 s.Equal(rulespec, []string{"-d", "1.1.1.1", "-j", "REJECT"}) 164 165 tablename, chainName, rulespec = s.iptables.AppendRuleArgsForCall(2) 166 s.Equal(tablename, "filter") 167 s.Equal(chainName, "CONCOURSE-OPERATOR") 168 s.Equal(rulespec, []string{"-d", "8.8.8.8", "-j", "REJECT"}) 169 } 170 171 func (s *CNINetworkSuite) TestAddNilTask() { 172 err := s.network.Add(context.Background(), nil) 173 s.EqualError(err, "nil task") 174 } 175 176 func (s *CNINetworkSuite) TestAddSetupErrors() { 177 s.cni.SetupReturns(nil, errors.New("setup-err")) 178 task := new(libcontainerdfakes.FakeTask) 179 180 err := s.network.Add(context.Background(), task) 181 s.EqualError(errors.Unwrap(err), "setup-err") 182 } 183 184 func (s *CNINetworkSuite) TestAdd() { 185 task := new(libcontainerdfakes.FakeTask) 186 task.PidReturns(123) 187 task.IDReturns("id") 188 189 err := s.network.Add(context.Background(), task) 190 s.NoError(err) 191 192 s.Equal(1, s.cni.SetupCallCount()) 193 _, id, netns, _ := s.cni.SetupArgsForCall(0) 194 s.Equal("id", id) 195 s.Equal("/proc/123/ns/net", netns) 196 } 197 198 func (s *CNINetworkSuite) TestRemoveNilTask() { 199 err := s.network.Remove(context.Background(), nil) 200 s.EqualError(err, "nil task") 201 } 202 203 func (s *CNINetworkSuite) TestRemoveSetupErrors() { 204 s.cni.RemoveReturns(errors.New("remove-err")) 205 task := new(libcontainerdfakes.FakeTask) 206 207 err := s.network.Remove(context.Background(), task) 208 s.EqualError(errors.Unwrap(err), "remove-err") 209 } 210 211 func (s *CNINetworkSuite) TestRemove() { 212 task := new(libcontainerdfakes.FakeTask) 213 task.PidReturns(123) 214 task.IDReturns("id") 215 216 err := s.network.Remove(context.Background(), task) 217 s.NoError(err) 218 219 s.Equal(1, s.cni.RemoveCallCount()) 220 _, id, netns, _ := s.cni.RemoveArgsForCall(0) 221 s.Equal("id", id) 222 s.Equal("/proc/123/ns/net", netns) 223 }