| // 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 devicepolicy | |
| import ( | |
| "crypto/x509" | |
| "errors" | |
| "io/ioutil" | |
| "os" | |
| "path/filepath" | |
| "policy-manager/pkg/sysapi" | |
| pb "policy-manager/protos" | |
| "reflect" | |
| "testing" | |
| "github.com/golang/protobuf/proto" | |
| ) | |
| var instanceConfig = &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(true), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(true), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| } | |
| type fileManager struct { | |
| TmpDir string | |
| TmpInstanceConfigFile string | |
| TmpDevicePolicyFile string | |
| TmpPublicKeyFile string | |
| TmpPrivateKeyFile string | |
| } | |
| // generateFakePolicyBytes is a helper function to generate device policy bytes | |
| // to simulate how device policy will be read from disk. | |
| func generateFakePolicyBytes(t *testing.T, config *pb.InstanceConfig) (instanceConfigPolicyBytes []byte) { | |
| // Create fake policy. | |
| t.Helper() | |
| fakePolicy := new(DevicePolicy) | |
| fakePolicy.SetFromInstanceConfig(config) | |
| instanceConfigPolicyBytes, err := proto.Marshal(fakePolicy.instanceConfig) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| return instanceConfigPolicyBytes | |
| } | |
| // generateTmpFiles is a function to generate a tmp directory and names of | |
| // device policy and key files. | |
| func generateTmpFiles(t *testing.T) fileManager { | |
| var err error | |
| fileMgr := fileManager{} | |
| fileMgr.TmpDir, err = ioutil.TempDir("", "policy_manager_test_") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| fileMgr.TmpInstanceConfigFile = filepath.Join(fileMgr.TmpDir, "instance_config") | |
| fileMgr.TmpDevicePolicyFile = filepath.Join(fileMgr.TmpDir, "policy") | |
| fileMgr.TmpPublicKeyFile = filepath.Join(fileMgr.TmpDir, "owner.key") | |
| fileMgr.TmpPrivateKeyFile = filepath.Join(fileMgr.TmpDir, "private.key") | |
| return fileMgr | |
| } | |
| // TestCreateKeyFiles tests that the function is writing to the keys to the | |
| // correct files with the right permissions. | |
| func TestCreateKeyFiles(t *testing.T) { | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| createKeyFiles(fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| // Check if the file exists | |
| if _, err := os.Stat(fileMgr.TmpPublicKeyFile); errors.Is(err, os.ErrNotExist) { | |
| t.Error("Public key file not created") | |
| } | |
| if _, err := os.Stat(fileMgr.TmpPrivateKeyFile); errors.Is(err, os.ErrNotExist) { | |
| t.Error("Private key file not created") | |
| } | |
| } | |
| // TestCheckKeyFiles tests that the checkKeyFiles function checks for the | |
| // existence of both the private and public key files as well as whether the | |
| // public and private keys match. | |
| func TestCheckKeyFiles(t *testing.T) { | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Generate another tmp policy file and key names | |
| newFileMgr := generateTmpFiles(t) | |
| createKeyFiles(fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile) | |
| createKeyFiles(newFileMgr.TmpPublicKeyFile, newFileMgr.TmpPrivateKeyFile) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| defer os.RemoveAll(newFileMgr.TmpDir) | |
| tests := []struct { | |
| name string | |
| publicKeyFile string | |
| privateKeyFile string | |
| expectErr bool | |
| }{ | |
| { | |
| "Good Key Pair", | |
| fileMgr.TmpPublicKeyFile, | |
| fileMgr.TmpPrivateKeyFile, | |
| false, | |
| }, | |
| { | |
| "Non-matching Key Pair", | |
| fileMgr.TmpPublicKeyFile, | |
| newFileMgr.TmpPrivateKeyFile, | |
| true, | |
| }, | |
| } | |
| for _, test := range tests { | |
| t.Run(test.name, func(t *testing.T) { | |
| privateKeyBytes, err := ioutil.ReadFile(test.privateKeyFile) | |
| if err != nil { | |
| t.Fatalf("error reading key file: %v", err) | |
| } | |
| privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBytes) | |
| if err != nil { | |
| t.Fatalf("error generating private key: %v", err) | |
| } | |
| privateKeyResult, err := checkKeyFiles(test.publicKeyFile, test.privateKeyFile) | |
| if err == nil { | |
| if test.expectErr { | |
| t.Errorf("test %s passed, expect error", | |
| test.name) | |
| } else if !reflect.DeepEqual(privateKeyResult, privateKey) { | |
| t.Errorf("test %s got private key %v, expect %v", | |
| test.name, privateKeyResult, privateKey) | |
| } | |
| } else { | |
| if !test.expectErr { | |
| t.Errorf("test %s got error %v, expect to pass", | |
| test.name, err) | |
| } | |
| } | |
| }) | |
| } | |
| } | |
| // TestInitDevicePolicyNoOnDiskPolicy tests the scenario where InitDevicePolicy() is called | |
| // with a nil InstanceConfig when one of device policy file missing. | |
| func TestInitDevicePolicyNoOnDiskPolicy(t *testing.T) { | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| expectedInstanceConfig := GetDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) | |
| expectedInstanceConfigBytes := generateFakePolicyBytes(t, expectedInstanceConfig) | |
| // Expect the policy files to be written. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, expectedInstanceConfigBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, expectedInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(expectedInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestInitDevicePolicyValidPolicy tests the scenario where InitDevicePolicy() is called | |
| // with a valid InstanceConfig when a device policy files already exist. In this case, | |
| // the files are re-written. | |
| func TestInitDevicePolicyValidPolicy(t *testing.T) { | |
| // Create fake policy. | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, instanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Initialization process should not create default policy files if the | |
| // existing policy files are valid. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| newInstanceConfig := GetDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) | |
| newInstanceConfigPolicyBytes := generateFakePolicyBytes(t, newInstanceConfig) | |
| // Expect the policy files to be written. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, newInstanceConfigPolicyBytes, configFilePerm) | |
| if err := InitDevicePolicy(&pb.InstanceConfig{}, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, newInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(newInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestInitDevicePolicyWithBasePolicy tests the InitDevicePolicy() function when a custom | |
| // base policy is specified. | |
| func TestInitDevicePolicyWithBasePolicy(t *testing.T) { | |
| // Create fake policy. | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, instanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| // Use custom base policy. | |
| newInstanceConfig := GetDefaultInstanceConfigFromBase( | |
| &pb.InstanceConfig{ | |
| UpdateStrategy: proto.String(""), | |
| }) | |
| newInstanceConfigPolicyBytes := generateFakePolicyBytes(t, newInstanceConfig) | |
| // Expect the policy to be written. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, newInstanceConfigPolicyBytes, configFilePerm) | |
| if err := InitDevicePolicy(newInstanceConfig, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, newInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(newInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestInitDevicePolicyWithoutBasePolicy tests that when baseConfig is nil but | |
| // there are existing device policy on disk, the existing device policy should | |
| // be populated with missing default fields and re-written to disk if changed. | |
| func TestInitDevicePolicyWithNilBasePolicy(t *testing.T) { | |
| // Create mock on-disk device policy. | |
| currentConfig := &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| } | |
| currentConfig = GetDefaultInstanceConfigFromBase(currentConfig) | |
| currentinstanceConfigPolicyBytes := generateFakePolicyBytes(t, currentConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Make sure the initialization process ensures that the policy | |
| // directory is present. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, currentinstanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, currentConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(currentConfig)) | |
| } | |
| } | |
| } | |
| // TestSetInstanceConfig_NewConfig tests whether the SetInstanceConfig function is able to | |
| // correctly write new device policy files to disk. | |
| func TestSetInstanceConfig_NewConfig(t *testing.T) { | |
| // Create fake policy. | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, instanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Policy file doesn't exist, so a new file should be created. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if err := SetInstanceConfig(instanceConfig, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, instanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(instanceConfig)) | |
| } | |
| } | |
| } | |
| // TestSetInstanceConfig_UpdatedConfig tests whether the SetInstanceConfig function is able to | |
| // correctly update the existing device policy file on disk. | |
| func TestSetInstanceConfig_UpdatedConfig(t *testing.T) { | |
| // Create fake policy. | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, instanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Policy files exist. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| // This is different than original instanceConfig. | |
| newInstanceConfig := GetDefaultInstanceConfigFromBase( | |
| &pb.InstanceConfig{ | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(false), | |
| }, | |
| }) | |
| newInstanceConfigPolicyBytes := generateFakePolicyBytes(t, newInstanceConfig) | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, newInstanceConfigPolicyBytes, configFilePerm) | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if err := SetInstanceConfig(newInstanceConfig, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, newInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(newInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestSetInstanceConfig_IdenticalConfig tests whether the SetInstanceConfig function skips | |
| // writing the policy files when there is no change in the instance config. | |
| func TestSetInstanceConfig_IdenticalConfig(t *testing.T) { | |
| // Create fake policy. | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, instanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Policy files exist. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| // AtomicWriteFile not expected since there is no change in the instanceConfig. | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if err := SetInstanceConfig(instanceConfig, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, instanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(instanceConfig)) | |
| } | |
| } | |
| } | |
| // TestSetInstanceConfig_EmptyConfig tests whether the SetInstanceConfig function sets | |
| // correct default values when an empty InstanceConfig is passed. | |
| func TestSetInstanceConfig_EmptyConfig(t *testing.T) { | |
| // Create fake policy. Start with default instnace config. | |
| defaultInstanceConfig := GetDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, defaultInstanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| // This is just an empty instnace config. | |
| emptyInstanceConfig := &pb.InstanceConfig{} | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if err := SetInstanceConfig(emptyInstanceConfig, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, defaultInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(defaultInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestSetInstanceConfig_NilConfig tests whether the SetInstanceConfig function sets | |
| // correct default values when an nil InstnaceConfig is passed. | |
| func TestSetInstanceConfig_NilConfig(t *testing.T) { | |
| // Create fake policy. Start with default instnace config. | |
| defaultInstanceConfig := GetDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, defaultInstanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if err := SetInstanceConfig(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, defaultInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(defaultInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestSetInstanceConfig_RemoveConfig tests whether the SetInstanceConfig function sets | |
| // correct default values for a removed config option. | |
| func TestSetInstanceConfig_RemoveConfig(t *testing.T) { | |
| // Create fake policy. | |
| instanceConfigPolicyBytes := generateFakePolicyBytes(t, instanceConfig) | |
| // Generate tmp policy file and key names | |
| fileMgr := generateTmpFiles(t) | |
| // Policy file exist; simulate its read. | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, instanceConfigPolicyBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpDir) | |
| // Note that MetricsEnabled is not specified. | |
| newInstanceConfig := &pb.InstanceConfig{ | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(true), | |
| }, | |
| } | |
| // expectedInstanceConfig is same as newInstanceConfig with default value for the | |
| // missing config option. | |
| expectedInstanceConfig := &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(true), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| } | |
| expectedInstanceConfigBytes := generateFakePolicyBytes(t, expectedInstanceConfig) | |
| sysapi.AtomicWriteFile(fileMgr.TmpInstanceConfigFile, expectedInstanceConfigBytes, configFilePerm) | |
| defer os.RemoveAll(fileMgr.TmpInstanceConfigFile) | |
| defer os.RemoveAll(fileMgr.TmpPublicKeyFile) | |
| defer os.RemoveAll(fileMgr.TmpPrivateKeyFile) | |
| defer os.RemoveAll(fileMgr.TmpDevicePolicyFile) | |
| if err := InitDevicePolicy(nil, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if err := SetInstanceConfig(newInstanceConfig, fileMgr.TmpDevicePolicyFile, fileMgr.TmpInstanceConfigFile, fileMgr.TmpPublicKeyFile, fileMgr.TmpPrivateKeyFile); err != nil { | |
| t.Error(err) | |
| } | |
| if generatedConfig, err := GetInstanceConfig(fileMgr.TmpInstanceConfigFile); err != nil { | |
| t.Error(err) | |
| } else { | |
| if !proto.Equal(generatedConfig, expectedInstanceConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(expectedInstanceConfig)) | |
| } | |
| } | |
| } | |
| // TestGetDefaultInstanceConfigFromBase tests that we always generate the expect default | |
| // update config. | |
| func TestGetDefaultInstanceConfigFromBase(t *testing.T) { | |
| // Expected default config. | |
| config := &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(false), | |
| LoggingEnabled: proto.Bool(false), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| } | |
| tests := []struct { | |
| name string | |
| baseConfig *pb.InstanceConfig | |
| expectedConfig *pb.InstanceConfig | |
| }{ | |
| { | |
| "NilBaseConfig", | |
| nil, | |
| config, | |
| }, | |
| { | |
| "EmptyBaseConfig", | |
| &pb.InstanceConfig{ | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{}, | |
| }, | |
| config, | |
| }, | |
| { | |
| "BaseConfigWithMetricsEnabled", | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(true), | |
| }, | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(true), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(false), | |
| LoggingEnabled: proto.Bool(false), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| }, | |
| }, | |
| { | |
| "BaseConfigWithUpdateStrategy", | |
| &pb.InstanceConfig{ | |
| UpdateStrategy: proto.String(""), | |
| }, | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(false), | |
| LoggingEnabled: proto.Bool(false), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| }, | |
| }, | |
| { | |
| "BaseConfigWithMultipleFields", | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(true), | |
| UpdateStrategy: proto.String(""), | |
| }, | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(true), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(false), | |
| LoggingEnabled: proto.Bool(false), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| }, | |
| }, | |
| { | |
| "BaseConfigEnablingLoggingMissingMonitoring", | |
| &pb.InstanceConfig{ | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(true), | |
| }, | |
| }, | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(true), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| }, | |
| }, | |
| { | |
| "BaseConfigEnforcedNotEnableLoggingMonitoring", | |
| &pb.InstanceConfig{ | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(false), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| }, | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(false), | |
| MonitoringEnabled: proto.Bool(false), | |
| }, | |
| }, | |
| }, | |
| { | |
| "BaseConfigEnableLoggingAndMonitoring", | |
| &pb.InstanceConfig{ | |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ | |
| Enforced: proto.Bool(true), | |
| LoggingEnabled: proto.Bool(true), | |
| MonitoringEnabled: proto.Bool(true), | |
| }, | |
| }, | |
| &pb.InstanceConfig{ | |
| MetricsEnabled: proto.Bool(false), | |
| UpdateStrategy: proto.String(""), | |
| HealthMonitorConfig: &pb.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) { | |
| generatedConfig := GetDefaultInstanceConfigFromBase(test.baseConfig) | |
| if !proto.Equal(generatedConfig, test.expectedConfig) { | |
| t.Errorf("got %s, expected %s", | |
| proto.MarshalTextString(generatedConfig), | |
| proto.MarshalTextString(test.expectedConfig)) | |
| } | |
| }) | |
| } | |
| } |