mirror of https://github.com/knative/client.git
Added the option to use --scale for setting MinScale and MaxScale to the same value (#914)
* Added the option to use --scale for setting MinScale and MaxScale to the same value * Updated service create/update to resolve test issues * Removed scale from the annotation section - there isn't a scale annotation * Renamed test service name so that it doesn't match a previous test * Addressed most issues/changes * Added tests for multiple flags being used at the same time * Cleaned up the update tests * Added negative value tests and cleaned up tests in create_test.go
This commit is contained in:
parent
41e49b98c5
commit
e1c48e6f7a
|
|
@ -88,6 +88,7 @@ kn service create NAME --image IMAGE
|
|||
--requests-cpu string DEPRECATED: please use --request instead. The requested CPU (e.g., 250m).
|
||||
--requests-memory string DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi).
|
||||
--revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}")
|
||||
--scale int Minimum and maximum number of replicas.
|
||||
--service-account string Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace.
|
||||
--user int The user ID to run the container (e.g., 1001).
|
||||
--volume stringArray Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-.
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ kn service update NAME
|
|||
--requests-cpu string DEPRECATED: please use --request instead. The requested CPU (e.g., 250m).
|
||||
--requests-memory string DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi).
|
||||
--revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}")
|
||||
--scale int Minimum and maximum number of replicas.
|
||||
--service-account string Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace.
|
||||
--tag strings Set tag (format: --tag revisionRef=tagName) where revisionRef can be a revision or '@latest' string representing latest ready revision. This flag can be specified multiple times.
|
||||
--traffic strings Set traffic distribution (format: --traffic revisionRef=percent) where revisionRef can be a revision or a tag or '@latest' string representing latest ready revision. This flag can be given multiple times with percent summing up to 100%.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ type ConfigurationEditFlags struct {
|
|||
|
||||
RequestsFlags, LimitsFlags ResourceFlags // TODO: Flag marked deprecated in release v0.15.0, remove in release v0.18.0
|
||||
Resources knflags.ResourceOptions
|
||||
Scale int
|
||||
MinScale int
|
||||
MaxScale int
|
||||
ConcurrencyTarget int
|
||||
|
|
@ -187,6 +188,9 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) {
|
|||
command.Flags().IntVar(&p.MaxScale, "max-scale", 0, "Maximal number of replicas.")
|
||||
p.markFlagMakesRevision("max-scale")
|
||||
|
||||
command.Flags().IntVar(&p.Scale, "scale", 0, "Minimum and maximum number of replicas.")
|
||||
p.markFlagMakesRevision("scale")
|
||||
|
||||
command.Flags().StringVar(&p.AutoscaleWindow, "autoscale-window", "", "Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)")
|
||||
p.markFlagMakesRevision("autoscale-window")
|
||||
|
||||
|
|
@ -437,6 +441,23 @@ func (p *ConfigurationEditFlags) Apply(
|
|||
}
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("scale") {
|
||||
if cmd.Flags().Changed("max-scale") {
|
||||
return fmt.Errorf("only --scale or --max-scale can be specified")
|
||||
} else if cmd.Flags().Changed("min-scale") {
|
||||
return fmt.Errorf("only --scale or --min-scale can be specified")
|
||||
} else {
|
||||
err = servinglib.UpdateMaxScale(template, p.Scale)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = servinglib.UpdateMinScale(template, p.Scale)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("autoscale-window") {
|
||||
err = servinglib.UpdateAutoscaleWindow(template, p.AutoscaleWindow)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -547,6 +547,76 @@ func TestServiceCreateMaxMinScale(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServiceCreateScale(t *testing.T) {
|
||||
action, created, _, err := fakeServiceCreate([]string{
|
||||
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz",
|
||||
"--scale", "5", "--no-wait"}, false)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !action.Matches("create", "services") {
|
||||
t.Fatalf("Bad action %v", action)
|
||||
}
|
||||
|
||||
template := &created.Spec.Template
|
||||
|
||||
actualAnnos := template.Annotations
|
||||
expectedAnnos := []string{
|
||||
"autoscaling.knative.dev/minScale", "5",
|
||||
"autoscaling.knative.dev/maxScale", "5",
|
||||
}
|
||||
|
||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||
anno := expectedAnnos[i]
|
||||
if actualAnnos[anno] != expectedAnnos[i+1] {
|
||||
t.Fatalf("Unexpected annotation value for %s : %s (actual) != %s (expected)",
|
||||
anno, actualAnnos[anno], expectedAnnos[i+1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceCreateScaleWithNegativeValue(t *testing.T) {
|
||||
_, _, _, err := fakeServiceCreate([]string{
|
||||
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz",
|
||||
"--scale", "-1", "--no-wait"}, true)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedErrMsg := "expected 0 <= -1 <= 2147483647: autoscaling.knative.dev/maxScale"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestServiceCreateScaleWithMaxScaleSet(t *testing.T) {
|
||||
_, _, _, err := fakeServiceCreate([]string{
|
||||
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz",
|
||||
"--scale", "5", "--max-scale", "2", "--no-wait"}, true)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedErrMsg := "only --scale or --max-scale can be specified"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestServiceCreateScaleWithMinScaleSet(t *testing.T) {
|
||||
_, _, _, err := fakeServiceCreate([]string{
|
||||
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz",
|
||||
"--scale", "5", "--min-scale", "2", "--no-wait"}, true)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedErrMsg := "only --scale or --min-scale can be specified"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestServiceCreateRequestsLimitsCPUMemory(t *testing.T) {
|
||||
action, created, _, err := fakeServiceCreate([]string{
|
||||
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz",
|
||||
|
|
|
|||
|
|
@ -355,6 +355,96 @@ func TestServiceUpdateMaxMinScale(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestServiceUpdateScale(t *testing.T) {
|
||||
original := newEmptyService()
|
||||
|
||||
action, updated, _, err := fakeServiceUpdate(original, []string{
|
||||
"service", "update", "foo",
|
||||
"--scale", "5", "--no-wait"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !action.Matches("update", "services") {
|
||||
t.Fatalf("Bad action %v", action)
|
||||
}
|
||||
|
||||
template := updated.Spec.Template
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actualAnnos := template.Annotations
|
||||
expectedAnnos := []string{
|
||||
"autoscaling.knative.dev/minScale", "5",
|
||||
"autoscaling.knative.dev/maxScale", "5",
|
||||
}
|
||||
|
||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||
anno := expectedAnnos[i]
|
||||
if actualAnnos[anno] != expectedAnnos[i+1] {
|
||||
t.Fatalf("Unexpected annotation value for %s : %s (actual) != %s (expected)",
|
||||
anno, actualAnnos[anno], expectedAnnos[i+1])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestServiceUpdateScaleWithNegativeValue(t *testing.T) {
|
||||
original := newEmptyService()
|
||||
|
||||
_, _, _, err := fakeServiceUpdate(original, []string{
|
||||
"service", "update", "foo",
|
||||
"--scale", "-1", "--no-wait"})
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Expected error, got nil")
|
||||
}
|
||||
|
||||
expectedErrMsg := "expected 0 <= -1 <= 2147483647: autoscaling.knative.dev/maxScale"
|
||||
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestServiceUpdateScaleWithMaxScaleSet(t *testing.T) {
|
||||
original := newEmptyService()
|
||||
|
||||
_, _, _, err := fakeServiceUpdate(original, []string{
|
||||
"service", "update", "foo",
|
||||
"--scale", "5", "--max-scale", "2", "--no-wait"})
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Expected error, got nil")
|
||||
}
|
||||
|
||||
expectedErrMsg := "only --scale or --max-scale can be specified"
|
||||
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestServiceUpdateScaleWithMinScaleSet(t *testing.T) {
|
||||
original := newEmptyService()
|
||||
|
||||
_, _, _, err := fakeServiceUpdate(original, []string{
|
||||
"service", "update", "foo",
|
||||
"--scale", "5", "--min-scale", "2", "--no-wait"})
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("Expected error, got nil")
|
||||
}
|
||||
|
||||
expectedErrMsg := "only --scale or --min-scale can be specified"
|
||||
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||
}
|
||||
|
||||
}
|
||||
func TestServiceUpdateEnv(t *testing.T) {
|
||||
orig := newEmptyService()
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func TestServiceOptions(t *testing.T) {
|
|||
t.Log("delete service")
|
||||
test.ServiceDelete(r, "svc1")
|
||||
|
||||
t.Log("create and validate service with min/max scale options ")
|
||||
t.Log("create and validate service with min/max scale options")
|
||||
serviceCreateWithOptions(r, "svc2", "--min-scale", "1", "--max-scale", "3")
|
||||
validateServiceMinScale(r, "svc2", "1")
|
||||
validateServiceMaxScale(r, "svc2", "3")
|
||||
|
|
@ -76,6 +76,16 @@ func TestServiceOptions(t *testing.T) {
|
|||
test.ServiceUpdate(r, "svc2", "--max-scale", "2")
|
||||
validateServiceMaxScale(r, "svc2", "2")
|
||||
|
||||
t.Log("create and validate service with scale options")
|
||||
serviceCreateWithOptions(r, "svc2a", "--scale", "5")
|
||||
validateServiceMinScale(r, "svc2a", "5")
|
||||
validateServiceMaxScale(r, "svc2a", "5")
|
||||
|
||||
t.Log("update and validate service with scale option")
|
||||
test.ServiceUpdate(r, "svc2a", "--scale", "2")
|
||||
validateServiceMaxScale(r, "svc2a", "2")
|
||||
validateServiceMinScale(r, "svc2a", "2")
|
||||
|
||||
t.Log("delete service")
|
||||
test.ServiceDelete(r, "svc2")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue