github.phpd.cn/cilium/cilium@v1.6.12/daemon/daemon_test.go (about) 1 // Copyright 2016-2019 Authors of Cilium 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 // +build !privileged_tests 16 17 package main 18 19 import ( 20 "context" 21 "io/ioutil" 22 "os" 23 "path/filepath" 24 "runtime" 25 "sync" 26 "testing" 27 "time" 28 29 "github.com/cilium/cilium/api/v1/models" 30 "github.com/cilium/cilium/common" 31 "github.com/cilium/cilium/pkg/completion" 32 "github.com/cilium/cilium/pkg/datapath" 33 fakedatapath "github.com/cilium/cilium/pkg/datapath/fake" 34 "github.com/cilium/cilium/pkg/endpoint/regeneration" 35 "github.com/cilium/cilium/pkg/endpointmanager" 36 "github.com/cilium/cilium/pkg/identity" 37 "github.com/cilium/cilium/pkg/identity/cache" 38 "github.com/cilium/cilium/pkg/kvstore" 39 "github.com/cilium/cilium/pkg/labels" 40 "github.com/cilium/cilium/pkg/lock" 41 "github.com/cilium/cilium/pkg/metrics" 42 monitorAPI "github.com/cilium/cilium/pkg/monitor/api" 43 "github.com/cilium/cilium/pkg/option" 44 "github.com/cilium/cilium/pkg/policy" 45 "github.com/cilium/cilium/pkg/proxy/accesslog" 46 "github.com/cilium/cilium/pkg/revert" 47 48 "github.com/prometheus/client_golang/prometheus" 49 . "gopkg.in/check.v1" 50 ) 51 52 // Hook up gocheck into the "go test" runner. 53 func Test(t *testing.T) { TestingT(t) } 54 55 type DaemonSuite struct { 56 d *Daemon 57 58 // oldPolicyEnabled is the policy enforcement mode that was set before the test, 59 // as returned by policy.GetPolicyEnabled(). 60 oldPolicyEnabled string 61 62 kvstoreInit bool 63 64 // Owners interface mock 65 OnTracingEnabled func() bool 66 OnAlwaysAllowLocalhost func() bool 67 OnGetCachedLabelList func(id identity.NumericIdentity) (labels.LabelArray, error) 68 OnGetPolicyRepository func() *policy.Repository 69 OnUpdateProxyRedirect func(e regeneration.EndpointUpdater, l4 *policy.L4Filter, proxyWaitGroup *completion.WaitGroup) (uint16, error, revert.FinalizeFunc, revert.RevertFunc) 70 OnRemoveProxyRedirect func(e regeneration.EndpointInfoSource, id string, proxyWaitGroup *completion.WaitGroup) (error, revert.FinalizeFunc, revert.RevertFunc) 71 OnUpdateNetworkPolicy func(e regeneration.EndpointUpdater, policy *policy.L4Policy, proxyWaitGroup *completion.WaitGroup) (error, revert.RevertFunc) 72 OnRemoveNetworkPolicy func(e regeneration.EndpointInfoSource) 73 OnQueueEndpointBuild func(ctx context.Context, epID uint64) (func(), error) 74 OnRemoveFromEndpointQueue func(epID uint64) 75 OnDebugEnabled func() bool 76 OnGetCompilationLock func() *lock.RWMutex 77 OnSendNotification func(typ monitorAPI.AgentNotification, text string) error 78 OnNewProxyLogRecord func(l *accesslog.LogRecord) error 79 OnClearPolicyConsumers func(id uint16) *sync.WaitGroup 80 81 // Metrics 82 collectors []prometheus.Collector 83 } 84 85 func setupTestDirectories() { 86 tempRunDir, err := ioutil.TempDir("", "cilium-test-run") 87 if err != nil { 88 panic("TempDir() failed.") 89 } 90 91 err = os.Mkdir(filepath.Join(tempRunDir, "globals"), 0777) 92 if err != nil { 93 panic("Mkdir failed") 94 } 95 96 option.Config.Device = "undefined" 97 option.Config.RunDir = tempRunDir 98 option.Config.StateDir = tempRunDir 99 option.Config.AccessLog = filepath.Join(tempRunDir, "cilium-access.log") 100 } 101 102 func TestMain(m *testing.M) { 103 // Set up all configuration options which are global to the entire test 104 // run. 105 option.Config.Populate() 106 option.Config.IdentityAllocationMode = option.IdentityAllocationModeKVstore 107 option.Config.DryMode = true 108 option.Config.Opts = option.NewIntOptions(&option.DaemonMutableOptionLibrary) 109 // GetConfig the default labels prefix filter 110 err := labels.ParseLabelPrefixCfg(nil, "") 111 if err != nil { 112 panic("ParseLabelPrefixCfg() failed") 113 } 114 option.Config.Opts.SetBool(option.DropNotify, true) 115 option.Config.Opts.SetBool(option.TraceNotify, true) 116 117 // Disable restore of host IPs for unit tests. There can be arbitrary 118 // state left on disk. 119 option.Config.EnableHostIPRestore = false 120 121 time.Local = time.UTC 122 os.Exit(m.Run()) 123 } 124 125 func (ds *DaemonSuite) SetUpSuite(c *C) { 126 // Register metrics once before running the suite 127 _, ds.collectors = metrics.CreateConfiguration([]string{"cilium_endpoint_state"}) 128 metrics.MustRegister(ds.collectors...) 129 } 130 131 func (ds *DaemonSuite) TearDownSuite(c *C) { 132 // Unregister the metrics after the suite has finished 133 for _, c := range ds.collectors { 134 metrics.Unregister(c) 135 } 136 } 137 138 func (ds *DaemonSuite) SetUpTest(c *C) { 139 140 setupTestDirectories() 141 142 ds.oldPolicyEnabled = policy.GetPolicyEnabled() 143 policy.SetPolicyEnabled(option.DefaultEnforcement) 144 145 d, _, err := NewDaemon(fakedatapath.NewDatapath(), nil) 146 c.Assert(err, IsNil) 147 ds.d = d 148 149 kvstore.Client().DeletePrefix(common.OperationalPath) 150 kvstore.Client().DeletePrefix(kvstore.BaseKeyPrefix) 151 152 ds.OnTracingEnabled = nil 153 ds.OnAlwaysAllowLocalhost = nil 154 ds.OnGetCachedLabelList = nil 155 ds.OnGetPolicyRepository = nil 156 ds.OnUpdateProxyRedirect = nil 157 ds.OnRemoveProxyRedirect = nil 158 ds.OnUpdateNetworkPolicy = nil 159 ds.OnRemoveNetworkPolicy = nil 160 ds.OnQueueEndpointBuild = nil 161 ds.OnRemoveFromEndpointQueue = nil 162 ds.OnDebugEnabled = nil 163 ds.OnGetCompilationLock = nil 164 ds.OnSendNotification = nil 165 ds.OnNewProxyLogRecord = nil 166 ds.OnClearPolicyConsumers = nil 167 168 // Reset the most common endpoint states before each test. 169 for _, s := range []string{ 170 string(models.EndpointStateReady), 171 string(models.EndpointStateWaitingForIdentity), 172 string(models.EndpointStateWaitingToRegenerate)} { 173 metrics.EndpointStateCount.WithLabelValues(s).Set(0.0) 174 } 175 } 176 177 func (ds *DaemonSuite) TearDownTest(c *C) { 178 endpointmanager.RemoveAll() 179 180 // It's helpful to keep the directories around if a test failed; only delete 181 // them if tests succeed. 182 if !c.Failed() { 183 os.RemoveAll(option.Config.RunDir) 184 } 185 186 if ds.kvstoreInit { 187 kvstore.Client().DeletePrefix(common.OperationalPath) 188 kvstore.Client().DeletePrefix(kvstore.BaseKeyPrefix) 189 } 190 191 // Restore the policy enforcement mode. 192 policy.SetPolicyEnabled(ds.oldPolicyEnabled) 193 194 // Release the identity allocator reference created by NewDaemon. This 195 // is done manually here as we have no Close() function daemon 196 cache.Close() 197 198 ds.d.Close() 199 } 200 201 type DaemonEtcdSuite struct { 202 DaemonSuite 203 } 204 205 var _ = Suite(&DaemonEtcdSuite{}) 206 207 func (e *DaemonEtcdSuite) SetUpSuite(c *C) { 208 kvstore.SetupDummy("etcd") 209 e.DaemonSuite.kvstoreInit = true 210 } 211 212 func (e *DaemonEtcdSuite) SetUpTest(c *C) { 213 e.DaemonSuite.SetUpTest(c) 214 } 215 216 func (e *DaemonEtcdSuite) TearDownTest(c *C) { 217 e.DaemonSuite.TearDownTest(c) 218 } 219 220 type DaemonConsulSuite struct { 221 DaemonSuite 222 } 223 224 var _ = Suite(&DaemonConsulSuite{}) 225 226 func (e *DaemonConsulSuite) SetUpSuite(c *C) { 227 kvstore.SetupDummy("consul") 228 e.DaemonSuite.kvstoreInit = true 229 } 230 231 func (e *DaemonConsulSuite) SetUpTest(c *C) { 232 e.DaemonSuite.SetUpTest(c) 233 } 234 235 func (e *DaemonConsulSuite) TearDownTest(c *C) { 236 e.DaemonSuite.TearDownTest(c) 237 } 238 239 func (ds *DaemonSuite) TestMinimumWorkerThreadsIsSet(c *C) { 240 c.Assert(numWorkerThreads() >= 2, Equals, true) 241 c.Assert(numWorkerThreads() >= runtime.NumCPU(), Equals, true) 242 } 243 244 func (ds *DaemonSuite) AlwaysAllowLocalhost() bool { 245 if ds.OnAlwaysAllowLocalhost != nil { 246 return ds.OnAlwaysAllowLocalhost() 247 } 248 panic("AlwaysAllowLocalhost should not have been called") 249 } 250 251 func (ds *DaemonSuite) GetCachedLabelList(id identity.NumericIdentity) (labels.LabelArray, error) { 252 if ds.OnGetCachedLabelList != nil { 253 return ds.OnGetCachedLabelList(id) 254 } 255 panic("GetCachedLabelList should not have been called") 256 } 257 258 func (ds *DaemonSuite) GetPolicyRepository() *policy.Repository { 259 if ds.OnGetPolicyRepository != nil { 260 return ds.OnGetPolicyRepository() 261 } 262 panic("GetPolicyRepository should not have been called") 263 } 264 265 func (ds *DaemonSuite) UpdateProxyRedirect(e regeneration.EndpointUpdater, l4 *policy.L4Filter, proxyWaitGroup *completion.WaitGroup) (uint16, error, revert.FinalizeFunc, revert.RevertFunc) { 266 if ds.OnUpdateProxyRedirect != nil { 267 return ds.OnUpdateProxyRedirect(e, l4, proxyWaitGroup) 268 } 269 panic("UpdateProxyRedirect should not have been called") 270 } 271 272 func (ds *DaemonSuite) RemoveProxyRedirect(e regeneration.EndpointInfoSource, id string, proxyWaitGroup *completion.WaitGroup) (error, revert.FinalizeFunc, revert.RevertFunc) { 273 if ds.OnRemoveProxyRedirect != nil { 274 return ds.OnRemoveProxyRedirect(e, id, proxyWaitGroup) 275 } 276 panic("RemoveProxyRedirect should not have been called") 277 } 278 279 func (ds *DaemonSuite) UpdateNetworkPolicy(e regeneration.EndpointUpdater, policy *policy.L4Policy, 280 proxyWaitGroup *completion.WaitGroup) (error, revert.RevertFunc) { 281 if ds.OnUpdateNetworkPolicy != nil { 282 return ds.OnUpdateNetworkPolicy(e, policy, proxyWaitGroup) 283 } 284 panic("UpdateNetworkPolicy should not have been called") 285 } 286 287 func (ds *DaemonSuite) RemoveNetworkPolicy(e regeneration.EndpointInfoSource) { 288 if ds.OnRemoveNetworkPolicy != nil { 289 ds.OnRemoveNetworkPolicy(e) 290 } 291 panic("RemoveNetworkPolicy should not have been called") 292 } 293 294 func (ds *DaemonSuite) QueueEndpointBuild(ctx context.Context, epID uint64) (func(), error) { 295 if ds.OnQueueEndpointBuild != nil { 296 return ds.OnQueueEndpointBuild(ctx, epID) 297 } 298 panic("QueueEndpointBuild should not have been called") 299 } 300 301 func (ds *DaemonSuite) RemoveFromEndpointQueue(epID uint64) { 302 if ds.OnRemoveFromEndpointQueue != nil { 303 ds.OnRemoveFromEndpointQueue(epID) 304 return 305 } 306 panic("RemoveFromEndpointQueue should not have been called") 307 } 308 309 func (ds *DaemonSuite) DebugEnabled() bool { 310 if ds.OnDebugEnabled != nil { 311 return ds.OnDebugEnabled() 312 } 313 panic("DebugEnabled should not have been called") 314 } 315 316 func (ds *DaemonSuite) GetCompilationLock() *lock.RWMutex { 317 if ds.OnGetCompilationLock != nil { 318 return ds.OnGetCompilationLock() 319 } 320 panic("GetCompilationLock should not have been called") 321 } 322 323 func (ds *DaemonSuite) SendNotification(typ monitorAPI.AgentNotification, text string) error { 324 if ds.OnSendNotification != nil { 325 return ds.OnSendNotification(typ, text) 326 } 327 panic("SendNotification should not have been called") 328 } 329 330 func (ds *DaemonSuite) NewProxyLogRecord(l *accesslog.LogRecord) error { 331 if ds.OnNewProxyLogRecord != nil { 332 return ds.OnNewProxyLogRecord(l) 333 } 334 panic("NewProxyLogRecord should not have been called") 335 } 336 337 func (ds *DaemonSuite) Datapath() datapath.Datapath { 338 return ds.d.datapath 339 } 340 341 func (ds *DaemonSuite) ClearPolicyConsumers(id uint16) *sync.WaitGroup { 342 if ds.OnClearPolicyConsumers != nil { 343 return ds.OnClearPolicyConsumers(id) 344 } 345 panic("ClearPolicyConsumers should not have been called") 346 } 347 348 func (ds *DaemonSuite) GetNodeSuffix() string { 349 return ds.d.GetNodeSuffix() 350 } 351 352 func (ds *DaemonSuite) UpdateIdentities(added, deleted cache.IdentityCache) { 353 ds.d.UpdateIdentities(added, deleted) 354 }