fake_runtime.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package testing
  14. import (
  15. "fmt"
  16. "io"
  17. "reflect"
  18. "sync"
  19. "time"
  20. "k8s.io/kubernetes/pkg/api"
  21. . "k8s.io/kubernetes/pkg/kubelet/container"
  22. "k8s.io/kubernetes/pkg/types"
  23. "k8s.io/kubernetes/pkg/util/flowcontrol"
  24. "k8s.io/kubernetes/pkg/util/term"
  25. "k8s.io/kubernetes/pkg/volume"
  26. )
  27. type FakePod struct {
  28. Pod *Pod
  29. NetnsPath string
  30. }
  31. // FakeRuntime is a fake container runtime for testing.
  32. type FakeRuntime struct {
  33. sync.Mutex
  34. CalledFunctions []string
  35. PodList []*FakePod
  36. AllPodList []*FakePod
  37. ImageList []Image
  38. APIPodStatus api.PodStatus
  39. PodStatus PodStatus
  40. StartedPods []string
  41. KilledPods []string
  42. StartedContainers []string
  43. KilledContainers []string
  44. VersionInfo string
  45. APIVersionInfo string
  46. RuntimeType string
  47. Err error
  48. InspectErr error
  49. StatusErr error
  50. }
  51. // FakeRuntime should implement Runtime.
  52. var _ Runtime = &FakeRuntime{}
  53. type FakeVersion struct {
  54. Version string
  55. }
  56. func (fv *FakeVersion) String() string {
  57. return fv.Version
  58. }
  59. func (fv *FakeVersion) Compare(other string) (int, error) {
  60. result := 0
  61. if fv.Version > other {
  62. result = 1
  63. } else if fv.Version < other {
  64. result = -1
  65. }
  66. return result, nil
  67. }
  68. type podsGetter interface {
  69. GetPods(bool) ([]*Pod, error)
  70. }
  71. type FakeRuntimeCache struct {
  72. getter podsGetter
  73. }
  74. func NewFakeRuntimeCache(getter podsGetter) RuntimeCache {
  75. return &FakeRuntimeCache{getter}
  76. }
  77. func (f *FakeRuntimeCache) GetPods() ([]*Pod, error) {
  78. return f.getter.GetPods(false)
  79. }
  80. func (f *FakeRuntimeCache) ForceUpdateIfOlder(time.Time) error {
  81. return nil
  82. }
  83. // ClearCalls resets the FakeRuntime to the initial state.
  84. func (f *FakeRuntime) ClearCalls() {
  85. f.Lock()
  86. defer f.Unlock()
  87. f.CalledFunctions = []string{}
  88. f.PodList = []*FakePod{}
  89. f.AllPodList = []*FakePod{}
  90. f.APIPodStatus = api.PodStatus{}
  91. f.StartedPods = []string{}
  92. f.KilledPods = []string{}
  93. f.StartedContainers = []string{}
  94. f.KilledContainers = []string{}
  95. f.VersionInfo = ""
  96. f.RuntimeType = ""
  97. f.Err = nil
  98. f.InspectErr = nil
  99. f.StatusErr = nil
  100. }
  101. func (f *FakeRuntime) assertList(expect []string, test []string) error {
  102. if !reflect.DeepEqual(expect, test) {
  103. return fmt.Errorf("expected %#v, got %#v", expect, test)
  104. }
  105. return nil
  106. }
  107. // AssertCalls test if the invoked functions are as expected.
  108. func (f *FakeRuntime) AssertCalls(calls []string) error {
  109. f.Lock()
  110. defer f.Unlock()
  111. return f.assertList(calls, f.CalledFunctions)
  112. }
  113. func (f *FakeRuntime) AssertStartedPods(pods []string) error {
  114. f.Lock()
  115. defer f.Unlock()
  116. return f.assertList(pods, f.StartedPods)
  117. }
  118. func (f *FakeRuntime) AssertKilledPods(pods []string) error {
  119. f.Lock()
  120. defer f.Unlock()
  121. return f.assertList(pods, f.KilledPods)
  122. }
  123. func (f *FakeRuntime) AssertStartedContainers(containers []string) error {
  124. f.Lock()
  125. defer f.Unlock()
  126. return f.assertList(containers, f.StartedContainers)
  127. }
  128. func (f *FakeRuntime) AssertKilledContainers(containers []string) error {
  129. f.Lock()
  130. defer f.Unlock()
  131. return f.assertList(containers, f.KilledContainers)
  132. }
  133. func (f *FakeRuntime) Type() string {
  134. return f.RuntimeType
  135. }
  136. func (f *FakeRuntime) Version() (Version, error) {
  137. f.Lock()
  138. defer f.Unlock()
  139. f.CalledFunctions = append(f.CalledFunctions, "Version")
  140. return &FakeVersion{Version: f.VersionInfo}, f.Err
  141. }
  142. func (f *FakeRuntime) APIVersion() (Version, error) {
  143. f.Lock()
  144. defer f.Unlock()
  145. f.CalledFunctions = append(f.CalledFunctions, "APIVersion")
  146. return &FakeVersion{Version: f.APIVersionInfo}, f.Err
  147. }
  148. func (f *FakeRuntime) Status() error {
  149. f.Lock()
  150. defer f.Unlock()
  151. f.CalledFunctions = append(f.CalledFunctions, "Status")
  152. return f.StatusErr
  153. }
  154. func (f *FakeRuntime) GetPods(all bool) ([]*Pod, error) {
  155. f.Lock()
  156. defer f.Unlock()
  157. var pods []*Pod
  158. f.CalledFunctions = append(f.CalledFunctions, "GetPods")
  159. if all {
  160. for _, fakePod := range f.AllPodList {
  161. pods = append(pods, fakePod.Pod)
  162. }
  163. } else {
  164. for _, fakePod := range f.PodList {
  165. pods = append(pods, fakePod.Pod)
  166. }
  167. }
  168. return pods, f.Err
  169. }
  170. func (f *FakeRuntime) SyncPod(pod *api.Pod, _ api.PodStatus, _ *PodStatus, _ []api.Secret, backOff *flowcontrol.Backoff) (result PodSyncResult) {
  171. f.Lock()
  172. defer f.Unlock()
  173. f.CalledFunctions = append(f.CalledFunctions, "SyncPod")
  174. f.StartedPods = append(f.StartedPods, string(pod.UID))
  175. for _, c := range pod.Spec.Containers {
  176. f.StartedContainers = append(f.StartedContainers, c.Name)
  177. }
  178. // TODO(random-liu): Add SyncResult for starting and killing containers
  179. if f.Err != nil {
  180. result.Fail(f.Err)
  181. }
  182. return
  183. }
  184. func (f *FakeRuntime) KillPod(pod *api.Pod, runningPod Pod, gracePeriodOverride *int64) error {
  185. f.Lock()
  186. defer f.Unlock()
  187. f.CalledFunctions = append(f.CalledFunctions, "KillPod")
  188. f.KilledPods = append(f.KilledPods, string(runningPod.ID))
  189. for _, c := range runningPod.Containers {
  190. f.KilledContainers = append(f.KilledContainers, c.Name)
  191. }
  192. return f.Err
  193. }
  194. func (f *FakeRuntime) RunContainerInPod(container api.Container, pod *api.Pod, volumeMap map[string]volume.VolumePlugin) error {
  195. f.Lock()
  196. defer f.Unlock()
  197. f.CalledFunctions = append(f.CalledFunctions, "RunContainerInPod")
  198. f.StartedContainers = append(f.StartedContainers, container.Name)
  199. pod.Spec.Containers = append(pod.Spec.Containers, container)
  200. for _, c := range pod.Spec.Containers {
  201. if c.Name == container.Name { // Container already in the pod.
  202. return f.Err
  203. }
  204. }
  205. pod.Spec.Containers = append(pod.Spec.Containers, container)
  206. return f.Err
  207. }
  208. func (f *FakeRuntime) KillContainerInPod(container api.Container, pod *api.Pod) error {
  209. f.Lock()
  210. defer f.Unlock()
  211. f.CalledFunctions = append(f.CalledFunctions, "KillContainerInPod")
  212. f.KilledContainers = append(f.KilledContainers, container.Name)
  213. var containers []api.Container
  214. for _, c := range pod.Spec.Containers {
  215. if c.Name == container.Name {
  216. continue
  217. }
  218. containers = append(containers, c)
  219. }
  220. return f.Err
  221. }
  222. func (f *FakeRuntime) GetPodStatus(uid types.UID, name, namespace string) (*PodStatus, error) {
  223. f.Lock()
  224. defer f.Unlock()
  225. f.CalledFunctions = append(f.CalledFunctions, "GetPodStatus")
  226. status := f.PodStatus
  227. return &status, f.Err
  228. }
  229. func (f *FakeRuntime) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error {
  230. f.Lock()
  231. defer f.Unlock()
  232. f.CalledFunctions = append(f.CalledFunctions, "ExecInContainer")
  233. return f.Err
  234. }
  235. func (f *FakeRuntime) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) error {
  236. f.Lock()
  237. defer f.Unlock()
  238. f.CalledFunctions = append(f.CalledFunctions, "AttachContainer")
  239. return f.Err
  240. }
  241. func (f *FakeRuntime) GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) {
  242. f.Lock()
  243. defer f.Unlock()
  244. f.CalledFunctions = append(f.CalledFunctions, "GetContainerLogs")
  245. return f.Err
  246. }
  247. func (f *FakeRuntime) PullImage(image ImageSpec, pullSecrets []api.Secret) error {
  248. f.Lock()
  249. defer f.Unlock()
  250. f.CalledFunctions = append(f.CalledFunctions, "PullImage")
  251. return f.Err
  252. }
  253. func (f *FakeRuntime) IsImagePresent(image ImageSpec) (bool, error) {
  254. f.Lock()
  255. defer f.Unlock()
  256. f.CalledFunctions = append(f.CalledFunctions, "IsImagePresent")
  257. for _, i := range f.ImageList {
  258. if i.ID == image.Image {
  259. return true, nil
  260. }
  261. }
  262. return false, f.InspectErr
  263. }
  264. func (f *FakeRuntime) ListImages() ([]Image, error) {
  265. f.Lock()
  266. defer f.Unlock()
  267. f.CalledFunctions = append(f.CalledFunctions, "ListImages")
  268. return f.ImageList, f.Err
  269. }
  270. func (f *FakeRuntime) RemoveImage(image ImageSpec) error {
  271. f.Lock()
  272. defer f.Unlock()
  273. f.CalledFunctions = append(f.CalledFunctions, "RemoveImage")
  274. index := 0
  275. for i := range f.ImageList {
  276. if f.ImageList[i].ID == image.Image {
  277. index = i
  278. break
  279. }
  280. }
  281. f.ImageList = append(f.ImageList[:index], f.ImageList[index+1:]...)
  282. return f.Err
  283. }
  284. func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteCloser) error {
  285. f.Lock()
  286. defer f.Unlock()
  287. f.CalledFunctions = append(f.CalledFunctions, "PortForward")
  288. return f.Err
  289. }
  290. func (f *FakeRuntime) GetNetNS(containerID ContainerID) (string, error) {
  291. f.Lock()
  292. defer f.Unlock()
  293. f.CalledFunctions = append(f.CalledFunctions, "GetNetNS")
  294. for _, fp := range f.AllPodList {
  295. for _, c := range fp.Pod.Containers {
  296. if c.ID == containerID {
  297. return fp.NetnsPath, nil
  298. }
  299. }
  300. }
  301. return "", f.Err
  302. }
  303. func (f *FakeRuntime) GetPodContainerID(pod *Pod) (ContainerID, error) {
  304. f.Lock()
  305. defer f.Unlock()
  306. f.CalledFunctions = append(f.CalledFunctions, "GetPodContainerID")
  307. return ContainerID{}, f.Err
  308. }
  309. func (f *FakeRuntime) GarbageCollect(gcPolicy ContainerGCPolicy, ready bool) error {
  310. f.Lock()
  311. defer f.Unlock()
  312. f.CalledFunctions = append(f.CalledFunctions, "GarbageCollect")
  313. return f.Err
  314. }
  315. func (f *FakeRuntime) DeleteContainer(containerID ContainerID) error {
  316. f.Lock()
  317. defer f.Unlock()
  318. f.CalledFunctions = append(f.CalledFunctions, "DeleteContainer")
  319. return f.Err
  320. }
  321. func (f *FakeRuntime) ImageStats() (*ImageStats, error) {
  322. f.Lock()
  323. defer f.Unlock()
  324. f.CalledFunctions = append(f.CalledFunctions, "ImageStats")
  325. return nil, f.Err
  326. }