| // Copyright 2021 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package configfetcher |
| |
| import ( |
| "fmt" |
| "net/http" |
| "net/http/httptest" |
| "testing" |
| |
| "github.com/golang/protobuf/proto" |
| "policy-manager/protos" |
| ) |
| |
| // Tests that all metadata keys are parsed and applied correctly. |
| func TestGetUserConfigFromMetadata(t *testing.T) { |
| tests := []struct { |
| // Name of the test case |
| name string |
| // Key:Value pairs present in metadata. |
| metadata map[string]string |
| // Expected InstanceConfig to be returned |
| expectedConfig *protos.InstanceConfig |
| }{ |
| { |
| "NoMetadataKeys", |
| map[string]string{}, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "UpdateStrategyPresent", |
| map[string]string{gciKeyUpdateStrategy: "update-strategy-1"}, |
| &protos.InstanceConfig{ |
| UpdateStrategy: proto.String(""), |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "MultipleSettingsPresent", |
| map[string]string{ |
| gciKeyUpdateStrategy: "update-strategy-2", |
| gciKeyMetricsEnabled: "true", |
| }, |
| &protos.InstanceConfig{ |
| UpdateStrategy: proto.String(""), |
| MetricsEnabled: proto.Bool(true), |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "InvalidBoolValueIgnored", |
| map[string]string{ |
| gciKeyMetricsEnabled: "no", |
| keyGoogleLoggingEnabled: "yes", |
| }, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "LegacyConfigKeyPresent", |
| map[string]string{ |
| gciLegacyConfigKey: "{\"update_strategy\":\"update-strategy-3\"}", |
| gciKeyUpdateStrategy: "update-strategy-4", |
| }, |
| &protos.InstanceConfig{ |
| UpdateStrategy: proto.String("update-strategy-3"), |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "LoggingButIngoreMonitoring", |
| map[string]string{ |
| keyGoogleLoggingEnabled: "true", |
| }, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| }, |
| }, |
| }, |
| { |
| "MonitoringButIngoreLogging", |
| map[string]string{ |
| keyGoogleMonitoringEnabled: "true", |
| }, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(true), |
| }, |
| }, |
| }, |
| { |
| "SpecifiedNoLogging", |
| map[string]string{ |
| keyGoogleLoggingEnabled: "false", |
| }, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| LoggingEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "LoggingAndMonitoring", |
| map[string]string{ |
| keyGoogleMonitoringEnabled: "true", |
| keyGoogleLoggingEnabled: "true", |
| }, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(true), |
| }, |
| }, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| actualConfig, _ := getUserConfigFromMetadata(test.metadata) |
| if !proto.Equal(actualConfig, test.expectedConfig) { |
| t.Errorf("FAILED '%s': got %s, expect %s", |
| test.name, |
| proto.MarshalTextString(actualConfig), |
| proto.MarshalTextString(test.expectedConfig)) |
| } |
| }) |
| } |
| } |
| |
| // Tests that getUserConfig() calls metadata client and |
| // returns correct config settings. |
| func TestGetUserConfig(t *testing.T) { |
| tests := []struct { |
| // Name of the test case |
| name string |
| // The metadata returned by metatdata client |
| metadata string |
| // The expected config settings to be returned |
| expectedConfig *protos.InstanceConfig |
| }{ |
| { |
| "NoMetadata", |
| "{}", |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "NormalUpdate", |
| `{ |
| "cos-metrics-enabled": "true", |
| "cos-update-strategy": "" |
| }`, |
| &protos.InstanceConfig{ |
| UpdateStrategy: proto.String(""), |
| MetricsEnabled: proto.Bool(true), |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "MixedUpdate", |
| `{ |
| "cos-update-strategy": "update_disabled", |
| "key1": "value1", |
| "kdy2": "value2" |
| }`, |
| &protos.InstanceConfig{ |
| UpdateStrategy: proto.String("update_disabled"), |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "NoCosMetadataUpdate", |
| `{ |
| "key1": "value1", |
| "kdy2": "value2" |
| }`, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{}, |
| }, |
| }, |
| { |
| "LoggingButNoMonitoring", |
| `{ |
| "google-logging-enabled": "true", |
| "google-monitoring-enabled": "false", |
| "key1": "value1", |
| "kdy2": "value2" |
| }`, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "MonitoringButIgnoreLogging", |
| `{ |
| "google-monitoring-enabled": "true", |
| "key1": "value1", |
| "kdy2": "value2" |
| }`, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(true), |
| }, |
| }, |
| }, |
| { |
| "LoggingAndMonitoring", |
| `{ |
| "google-logging-enabled": "true", |
| "google-monitoring-enabled": "true", |
| "key1": "value1", |
| "kdy2": "value2" |
| }`, |
| &protos.InstanceConfig{ |
| HealthMonitorConfig: &protos.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(true), |
| }, |
| }, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| // Set up a test server. |
| handler := func(w http.ResponseWriter, r *http.Request) { |
| // Make sure the request is for the directory. |
| if r.URL.Path != instanceCustomDataDirectory { |
| t.Errorf("got URL path %s, want %s", |
| r.URL.Path, |
| instanceCustomDataDirectory) |
| } |
| |
| expectedQuery := "recursive=true" |
| if r.URL.RawQuery != expectedQuery { |
| t.Errorf("got HTTP request query %s, want %s", |
| r.URL.RawQuery, |
| expectedQuery) |
| } |
| |
| w.Header().Set("etag", "") |
| |
| fmt.Fprint(w, test.metadata) |
| } |
| ts := httptest.NewServer(http.HandlerFunc(handler)) |
| |
| actualConfig, _, _ := getUserConfig("", ts.URL) |
| |
| if !proto.Equal(actualConfig, test.expectedConfig) { |
| t.Errorf("FAILED '%s': got %s, expect %s", |
| test.name, |
| proto.MarshalTextString(actualConfig), |
| proto.MarshalTextString(test.expectedConfig)) |
| } |
| }) |
| } |
| } |