Merge pull request #91885 from iamchuckss/test-throttling-image-service
Add test coverage for throttledImageService
This commit is contained in:
		@@ -37,29 +37,38 @@ type pullerExpects struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type pullerTestCase struct {
 | 
					type pullerTestCase struct {
 | 
				
			||||||
 | 
						testName       string
 | 
				
			||||||
	containerImage string
 | 
						containerImage string
 | 
				
			||||||
	policy         v1.PullPolicy
 | 
						policy         v1.PullPolicy
 | 
				
			||||||
	inspectErr     error
 | 
						inspectErr     error
 | 
				
			||||||
	pullerErr      error
 | 
						pullerErr      error
 | 
				
			||||||
 | 
						qps            float32
 | 
				
			||||||
 | 
						burst          int
 | 
				
			||||||
	expected       []pullerExpects
 | 
						expected       []pullerExpects
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func pullerTestCases() []pullerTestCase {
 | 
					func pullerTestCases() []pullerTestCase {
 | 
				
			||||||
	return []pullerTestCase{
 | 
						return []pullerTestCase{
 | 
				
			||||||
		{ // pull missing image
 | 
							{ // pull missing image
 | 
				
			||||||
 | 
								testName:       "image missing, pull",
 | 
				
			||||||
			containerImage: "missing_image",
 | 
								containerImage: "missing_image",
 | 
				
			||||||
			policy:         v1.PullIfNotPresent,
 | 
								policy:         v1.PullIfNotPresent,
 | 
				
			||||||
			inspectErr:     nil,
 | 
								inspectErr:     nil,
 | 
				
			||||||
			pullerErr:      nil,
 | 
								pullerErr:      nil,
 | 
				
			||||||
 | 
								qps:            0.0,
 | 
				
			||||||
 | 
								burst:          0,
 | 
				
			||||||
			expected: []pullerExpects{
 | 
								expected: []pullerExpects{
 | 
				
			||||||
				{[]string{"GetImageRef", "PullImage"}, nil},
 | 
									{[]string{"GetImageRef", "PullImage"}, nil},
 | 
				
			||||||
			}},
 | 
								}},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{ // image present, don't pull
 | 
							{ // image present, don't pull
 | 
				
			||||||
 | 
								testName:       "image present, don't pull ",
 | 
				
			||||||
			containerImage: "present_image",
 | 
								containerImage: "present_image",
 | 
				
			||||||
			policy:         v1.PullIfNotPresent,
 | 
								policy:         v1.PullIfNotPresent,
 | 
				
			||||||
			inspectErr:     nil,
 | 
								inspectErr:     nil,
 | 
				
			||||||
			pullerErr:      nil,
 | 
								pullerErr:      nil,
 | 
				
			||||||
 | 
								qps:            0.0,
 | 
				
			||||||
 | 
								burst:          0,
 | 
				
			||||||
			expected: []pullerExpects{
 | 
								expected: []pullerExpects{
 | 
				
			||||||
				{[]string{"GetImageRef"}, nil},
 | 
									{[]string{"GetImageRef"}, nil},
 | 
				
			||||||
				{[]string{"GetImageRef"}, nil},
 | 
									{[]string{"GetImageRef"}, nil},
 | 
				
			||||||
@@ -67,9 +76,12 @@ func pullerTestCases() []pullerTestCase {
 | 
				
			|||||||
			}},
 | 
								}},
 | 
				
			||||||
		// image present, pull it
 | 
							// image present, pull it
 | 
				
			||||||
		{containerImage: "present_image",
 | 
							{containerImage: "present_image",
 | 
				
			||||||
 | 
								testName:   "image present, pull ",
 | 
				
			||||||
			policy:     v1.PullAlways,
 | 
								policy:     v1.PullAlways,
 | 
				
			||||||
			inspectErr: nil,
 | 
								inspectErr: nil,
 | 
				
			||||||
			pullerErr:  nil,
 | 
								pullerErr:  nil,
 | 
				
			||||||
 | 
								qps:        0.0,
 | 
				
			||||||
 | 
								burst:      0,
 | 
				
			||||||
			expected: []pullerExpects{
 | 
								expected: []pullerExpects{
 | 
				
			||||||
				{[]string{"GetImageRef", "PullImage"}, nil},
 | 
									{[]string{"GetImageRef", "PullImage"}, nil},
 | 
				
			||||||
				{[]string{"GetImageRef", "PullImage"}, nil},
 | 
									{[]string{"GetImageRef", "PullImage"}, nil},
 | 
				
			||||||
@@ -77,9 +89,12 @@ func pullerTestCases() []pullerTestCase {
 | 
				
			|||||||
			}},
 | 
								}},
 | 
				
			||||||
		// missing image, error PullNever
 | 
							// missing image, error PullNever
 | 
				
			||||||
		{containerImage: "missing_image",
 | 
							{containerImage: "missing_image",
 | 
				
			||||||
 | 
								testName:   "image missing, never pull",
 | 
				
			||||||
			policy:     v1.PullNever,
 | 
								policy:     v1.PullNever,
 | 
				
			||||||
			inspectErr: nil,
 | 
								inspectErr: nil,
 | 
				
			||||||
			pullerErr:  nil,
 | 
								pullerErr:  nil,
 | 
				
			||||||
 | 
								qps:        0.0,
 | 
				
			||||||
 | 
								burst:      0,
 | 
				
			||||||
			expected: []pullerExpects{
 | 
								expected: []pullerExpects{
 | 
				
			||||||
				{[]string{"GetImageRef"}, ErrImageNeverPull},
 | 
									{[]string{"GetImageRef"}, ErrImageNeverPull},
 | 
				
			||||||
				{[]string{"GetImageRef"}, ErrImageNeverPull},
 | 
									{[]string{"GetImageRef"}, ErrImageNeverPull},
 | 
				
			||||||
@@ -87,9 +102,12 @@ func pullerTestCases() []pullerTestCase {
 | 
				
			|||||||
			}},
 | 
								}},
 | 
				
			||||||
		// missing image, unable to inspect
 | 
							// missing image, unable to inspect
 | 
				
			||||||
		{containerImage: "missing_image",
 | 
							{containerImage: "missing_image",
 | 
				
			||||||
 | 
								testName:   "image missing, pull if not present",
 | 
				
			||||||
			policy:     v1.PullIfNotPresent,
 | 
								policy:     v1.PullIfNotPresent,
 | 
				
			||||||
			inspectErr: errors.New("unknown inspectError"),
 | 
								inspectErr: errors.New("unknown inspectError"),
 | 
				
			||||||
			pullerErr:  nil,
 | 
								pullerErr:  nil,
 | 
				
			||||||
 | 
								qps:        0.0,
 | 
				
			||||||
 | 
								burst:      0,
 | 
				
			||||||
			expected: []pullerExpects{
 | 
								expected: []pullerExpects{
 | 
				
			||||||
				{[]string{"GetImageRef"}, ErrImageInspect},
 | 
									{[]string{"GetImageRef"}, ErrImageInspect},
 | 
				
			||||||
				{[]string{"GetImageRef"}, ErrImageInspect},
 | 
									{[]string{"GetImageRef"}, ErrImageInspect},
 | 
				
			||||||
@@ -97,9 +115,12 @@ func pullerTestCases() []pullerTestCase {
 | 
				
			|||||||
			}},
 | 
								}},
 | 
				
			||||||
		// missing image, unable to fetch
 | 
							// missing image, unable to fetch
 | 
				
			||||||
		{containerImage: "typo_image",
 | 
							{containerImage: "typo_image",
 | 
				
			||||||
 | 
								testName:   "image missing, unable to fetch",
 | 
				
			||||||
			policy:     v1.PullIfNotPresent,
 | 
								policy:     v1.PullIfNotPresent,
 | 
				
			||||||
			inspectErr: nil,
 | 
								inspectErr: nil,
 | 
				
			||||||
			pullerErr:  errors.New("404"),
 | 
								pullerErr:  errors.New("404"),
 | 
				
			||||||
 | 
								qps:        0.0,
 | 
				
			||||||
 | 
								burst:      0,
 | 
				
			||||||
			expected: []pullerExpects{
 | 
								expected: []pullerExpects{
 | 
				
			||||||
				{[]string{"GetImageRef", "PullImage"}, ErrImagePull},
 | 
									{[]string{"GetImageRef", "PullImage"}, ErrImagePull},
 | 
				
			||||||
				{[]string{"GetImageRef", "PullImage"}, ErrImagePull},
 | 
									{[]string{"GetImageRef", "PullImage"}, ErrImagePull},
 | 
				
			||||||
@@ -108,6 +129,32 @@ func pullerTestCases() []pullerTestCase {
 | 
				
			|||||||
				{[]string{"GetImageRef"}, ErrImagePullBackOff},
 | 
									{[]string{"GetImageRef"}, ErrImagePullBackOff},
 | 
				
			||||||
				{[]string{"GetImageRef"}, ErrImagePullBackOff},
 | 
									{[]string{"GetImageRef"}, ErrImagePullBackOff},
 | 
				
			||||||
			}},
 | 
								}},
 | 
				
			||||||
 | 
							// image present, non-zero qps, try to pull
 | 
				
			||||||
 | 
							{containerImage: "present_image",
 | 
				
			||||||
 | 
								testName:   "image present and qps>0, pull",
 | 
				
			||||||
 | 
								policy:     v1.PullAlways,
 | 
				
			||||||
 | 
								inspectErr: nil,
 | 
				
			||||||
 | 
								pullerErr:  nil,
 | 
				
			||||||
 | 
								qps:        400.0,
 | 
				
			||||||
 | 
								burst:      600,
 | 
				
			||||||
 | 
								expected: []pullerExpects{
 | 
				
			||||||
 | 
									{[]string{"GetImageRef", "PullImage"}, nil},
 | 
				
			||||||
 | 
									{[]string{"GetImageRef", "PullImage"}, nil},
 | 
				
			||||||
 | 
									{[]string{"GetImageRef", "PullImage"}, nil},
 | 
				
			||||||
 | 
								}},
 | 
				
			||||||
 | 
							// image present, non-zero qps, try to pull when qps exceeded
 | 
				
			||||||
 | 
							{containerImage: "present_image",
 | 
				
			||||||
 | 
								testName:   "image present and excessive qps rate, pull",
 | 
				
			||||||
 | 
								policy:     v1.PullAlways,
 | 
				
			||||||
 | 
								inspectErr: nil,
 | 
				
			||||||
 | 
								pullerErr:  nil,
 | 
				
			||||||
 | 
								qps:        2000.0,
 | 
				
			||||||
 | 
								burst:      0,
 | 
				
			||||||
 | 
								expected: []pullerExpects{
 | 
				
			||||||
 | 
									{[]string{"GetImageRef"}, ErrImagePull},
 | 
				
			||||||
 | 
									{[]string{"GetImageRef"}, ErrImagePull},
 | 
				
			||||||
 | 
									{[]string{"GetImageRef"}, ErrImagePullBackOff},
 | 
				
			||||||
 | 
								}},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -129,7 +176,7 @@ func pullerTestEnv(c pullerTestCase, serialized bool) (puller ImageManager, fake
 | 
				
			|||||||
	fakeRuntime.Err = c.pullerErr
 | 
						fakeRuntime.Err = c.pullerErr
 | 
				
			||||||
	fakeRuntime.InspectErr = c.inspectErr
 | 
						fakeRuntime.InspectErr = c.inspectErr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	puller = NewImageManager(fakeRecorder, fakeRuntime, backOff, serialized, 0, 0)
 | 
						puller = NewImageManager(fakeRecorder, fakeRuntime, backOff, serialized, c.qps, c.burst)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -146,16 +193,18 @@ func TestParallelPuller(t *testing.T) {
 | 
				
			|||||||
	cases := pullerTestCases()
 | 
						cases := pullerTestCases()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	useSerializedEnv := false
 | 
						useSerializedEnv := false
 | 
				
			||||||
	for i, c := range cases {
 | 
						for _, c := range cases {
 | 
				
			||||||
		puller, fakeClock, fakeRuntime, container := pullerTestEnv(c, useSerializedEnv)
 | 
							puller, fakeClock, fakeRuntime, container := pullerTestEnv(c, useSerializedEnv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for tick, expected := range c.expected {
 | 
							t.Run(c.testName, func(t *testing.T) {
 | 
				
			||||||
 | 
								for _, expected := range c.expected {
 | 
				
			||||||
				fakeRuntime.CalledFunctions = nil
 | 
									fakeRuntime.CalledFunctions = nil
 | 
				
			||||||
				fakeClock.Step(time.Second)
 | 
									fakeClock.Step(time.Second)
 | 
				
			||||||
				_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
 | 
									_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
 | 
				
			||||||
			assert.NoError(t, fakeRuntime.AssertCalls(expected.calls), "in test %d tick=%d", i, tick)
 | 
									assert.NoError(t, fakeRuntime.AssertCalls(expected.calls))
 | 
				
			||||||
			assert.Equal(t, expected.err, err, "in test %d tick=%d", i, tick)
 | 
									assert.Equal(t, expected.err, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -172,34 +221,39 @@ func TestSerializedPuller(t *testing.T) {
 | 
				
			|||||||
	cases := pullerTestCases()
 | 
						cases := pullerTestCases()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	useSerializedEnv := true
 | 
						useSerializedEnv := true
 | 
				
			||||||
	for i, c := range cases {
 | 
						for _, c := range cases {
 | 
				
			||||||
		puller, fakeClock, fakeRuntime, container := pullerTestEnv(c, useSerializedEnv)
 | 
							puller, fakeClock, fakeRuntime, container := pullerTestEnv(c, useSerializedEnv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for tick, expected := range c.expected {
 | 
							t.Run(c.testName, func(t *testing.T) {
 | 
				
			||||||
 | 
								for _, expected := range c.expected {
 | 
				
			||||||
				fakeRuntime.CalledFunctions = nil
 | 
									fakeRuntime.CalledFunctions = nil
 | 
				
			||||||
				fakeClock.Step(time.Second)
 | 
									fakeClock.Step(time.Second)
 | 
				
			||||||
				_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
 | 
									_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
 | 
				
			||||||
			assert.NoError(t, fakeRuntime.AssertCalls(expected.calls), "in test %d tick=%d", i, tick)
 | 
									assert.NoError(t, fakeRuntime.AssertCalls(expected.calls))
 | 
				
			||||||
			assert.Equal(t, expected.err, err, "in test %d tick=%d", i, tick)
 | 
									assert.Equal(t, expected.err, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestApplyDefaultImageTag(t *testing.T) {
 | 
					func TestApplyDefaultImageTag(t *testing.T) {
 | 
				
			||||||
	for _, testCase := range []struct {
 | 
						for _, testCase := range []struct {
 | 
				
			||||||
 | 
							testName string
 | 
				
			||||||
		Input    string
 | 
							Input    string
 | 
				
			||||||
		Output   string
 | 
							Output   string
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{Input: "root", Output: "root:latest"},
 | 
							{testName: "root", Input: "root", Output: "root:latest"},
 | 
				
			||||||
		{Input: "root:tag", Output: "root:tag"},
 | 
							{testName: "root:tag", Input: "root:tag", Output: "root:tag"},
 | 
				
			||||||
		{Input: "root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Output: "root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
 | 
							{testName: "root@sha", Input: "root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Output: "root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
 | 
				
			||||||
	} {
 | 
						} {
 | 
				
			||||||
 | 
							t.Run(testCase.testName, func(t *testing.T) {
 | 
				
			||||||
			image, err := applyDefaultImageTag(testCase.Input)
 | 
								image, err := applyDefaultImageTag(testCase.Input)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Errorf("applyDefaultImageTag(%s) failed: %v", testCase.Input, err)
 | 
									t.Errorf("applyDefaultImageTag(%s) failed: %v", testCase.Input, err)
 | 
				
			||||||
			} else if image != testCase.Output {
 | 
								} else if image != testCase.Output {
 | 
				
			||||||
				t.Errorf("Expected image reference: %q, got %q", testCase.Output, image)
 | 
									t.Errorf("Expected image reference: %q, got %q", testCase.Output, image)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -216,6 +270,7 @@ func TestPullAndListImageWithPodAnnotations(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		}}
 | 
							}}
 | 
				
			||||||
	c := pullerTestCase{ // pull missing image
 | 
						c := pullerTestCase{ // pull missing image
 | 
				
			||||||
 | 
							testName:       "test pull and list image with pod annotations",
 | 
				
			||||||
		containerImage: "missing_image",
 | 
							containerImage: "missing_image",
 | 
				
			||||||
		policy:         v1.PullIfNotPresent,
 | 
							policy:         v1.PullIfNotPresent,
 | 
				
			||||||
		inspectErr:     nil,
 | 
							inspectErr:     nil,
 | 
				
			||||||
@@ -230,6 +285,7 @@ func TestPullAndListImageWithPodAnnotations(t *testing.T) {
 | 
				
			|||||||
	fakeRuntime.ImageList = []Image{}
 | 
						fakeRuntime.ImageList = []Image{}
 | 
				
			||||||
	fakeClock.Step(time.Second)
 | 
						fakeClock.Step(time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Run(c.testName, func(t *testing.T) {
 | 
				
			||||||
		_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
 | 
							_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
 | 
				
			||||||
		assert.NoError(t, fakeRuntime.AssertCalls(c.expected[0].calls), "tick=%d", 0)
 | 
							assert.NoError(t, fakeRuntime.AssertCalls(c.expected[0].calls), "tick=%d", 0)
 | 
				
			||||||
		assert.Equal(t, c.expected[0].err, err, "tick=%d", 0)
 | 
							assert.Equal(t, c.expected[0].err, err, "tick=%d", 0)
 | 
				
			||||||
@@ -246,4 +302,5 @@ func TestPullAndListImageWithPodAnnotations(t *testing.T) {
 | 
				
			|||||||
				Value: "handler_name",
 | 
									Value: "handler_name",
 | 
				
			||||||
			}}
 | 
								}}
 | 
				
			||||||
		assert.Equal(t, expectedAnnotations, image.Spec.Annotations, "image spec annotations")
 | 
							assert.Equal(t, expectedAnnotations, image.Spec.Annotations, "image spec annotations")
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user