| // 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/rand" |
| "crypto/rsa" |
| "crypto/x509" |
| "os" |
| "path/filepath" |
| "reflect" |
| "testing" |
| |
| "policy_manager/mock/mocksysapi" |
| pb "policy_manager/policymanagerproto" |
| |
| "github.com/golang/mock/gomock" |
| "github.com/golang/protobuf/proto" |
| ) |
| |
| var instanceConfig = &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(true), |
| TargetVersionPrefix: proto.String("7099."), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(0), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| } |
| |
| // 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, key *rsa.PrivateKey, config *pb.InstanceConfig) (policyBytes []byte, cosDevicePolicyBytes []byte) { |
| // Create mock policy. |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)).AnyTimes() |
| |
| policy := new(DevicePolicy) |
| policy.SetFromInstanceConfig(config) |
| policyFetchResponse, err := policy.generateDevicePolicy(key, mockAPI) |
| if err != nil { |
| t.Fatal(err) |
| } |
| policyBytes, err = proto.Marshal(policyFetchResponse) |
| if err != nil { |
| t.Fatal(err) |
| } |
| cosDevicePolicyBytes, err = proto.Marshal(policy.cosDevicePolicy) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| return policyBytes, cosDevicePolicyBytes |
| } |
| |
| func genInterceptPolicy(t *testing.T, expectBytes []byte) func(string, []byte, os.FileMode) { |
| return func(_ string, content []byte, _ os.FileMode) { |
| if !reflect.DeepEqual(expectBytes, content) { |
| t.Errorf("In test %v, got policy: %v, expect: %v", t.Name(), content, expectBytes) |
| } |
| } |
| } |
| |
| // TestCreateKeyFiles tests that the function is writing to the keys to the |
| // correct files with the right permissions. |
| func TestCreateKeyFiles(t *testing.T) { |
| // Set up gomock controller. |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| mockAPI.EXPECT().WriteFile(publicKeyFile, gomock.Any(), keyFilePerm). |
| Return(nil) |
| mockAPI.EXPECT().WriteFile(privateKeyFile, gomock.Any(), keyFilePerm). |
| Return(nil) |
| |
| if _, err := createKeyFiles(mockAPI); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKey2, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public() |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| privateKeyBytes2 := x509.MarshalPKCS1PrivateKey(privateKey2) |
| |
| tests := []struct { |
| name string |
| publicKeyBytes []byte |
| privateKeyBytes []byte |
| privateKey *rsa.PrivateKey |
| expectErr bool |
| }{ |
| { |
| "Good Key Pair", |
| publicKeyBytes, |
| privateKeyBytes, |
| privateKey, |
| false, |
| }, |
| { |
| "Bad Public Key Encoding", |
| []byte("abc"), |
| privateKeyBytes, |
| nil, |
| true, |
| }, |
| { |
| "Bad Private Key Encoding", |
| publicKeyBytes, |
| []byte("abc"), |
| nil, |
| true, |
| }, |
| { |
| "Non-matching Key Pair", |
| publicKeyBytes, |
| privateKeyBytes2, |
| nil, |
| true, |
| }, |
| } |
| |
| for _, test := range tests { |
| mockCtrl := gomock.NewController(t) |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| mockAPI.EXPECT().ReadFile(publicKeyFile). |
| Return(test.publicKeyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(privateKeyFile). |
| Return(test.privateKeyBytes, nil).AnyTimes() |
| |
| privateKeyResult, err := checkKeyFiles(mockAPI) |
| |
| if err == nil { |
| if test.expectErr { |
| t.Errorf("test %s passed, expect error", |
| test.name) |
| } else if !reflect.DeepEqual(privateKeyResult, test.privateKey) { |
| t.Errorf("test %s got private key %v, expect %v", |
| test.name, privateKeyResult, test.privateKey) |
| } |
| } else { |
| if !test.expectErr { |
| t.Errorf("test %s got error %v, expect to pass", |
| test.name, err) |
| } |
| } |
| |
| mockCtrl.Finish() |
| } |
| } |
| |
| // TestInitDevicePolicyCreateKeyFiles tests that InitDevicePolicy() creates |
| // new key files if key files if they are not present. |
| func TestInitDevicePolicyCreateKeyFiles(t *testing.T) { |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| policyDir := filepath.Dir(policyFile) |
| mockAPI.EXPECT().MkdirAll(policyDir, policyFilePerm).Return(nil) |
| |
| // Create mock private/public key. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| // The initialization process should create new key files if they don't |
| // exist and read them back for writing the default policy file. |
| privateNotExist := mockAPI.EXPECT().FileExists(privateKeyFile).Return(false).AnyTimes() |
| writeToPrivate := mockAPI.EXPECT().WriteFile(privateKeyFile, gomock.Any(), keyFilePerm).Return(nil).After(privateNotExist) |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes().After(writeToPrivate) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil).AnyTimes().After(writeToPrivate) |
| |
| publicNotExist := mockAPI.EXPECT().FileExists(publicKeyFile).Return(false).AnyTimes() |
| writeToPublic := mockAPI.EXPECT().WriteFile(publicKeyFile, gomock.Any(), keyFilePerm).Return(nil).After(publicNotExist) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes().After(writeToPublic) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes().After(writeToPublic) |
| |
| // Initialization process should create two default policy files. |
| gomock.InOrder( |
| mockAPI.EXPECT().FileExists(policyFile).Return(false).AnyTimes(), |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)), |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), policyFilePerm).Return(nil), |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes(), |
| ) |
| gomock.InOrder( |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(false).AnyTimes(), |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), cosDevicePolicyFilePerm).Return(nil), |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true).AnyTimes(), |
| ) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(nil); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestInitDevicePolicyCheckKeyFiles tests that InitDevicePolicy() checks the |
| // content of key files and creates new key files if the keys are not valid. |
| func TestInitDevicePolicyCheckKeyFiles(t *testing.T) { |
| // Create mock private/public key. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| policyDir := filepath.Dir(policyFile) |
| mockAPI.EXPECT().MkdirAll(policyDir, policyFilePerm).Return(nil) |
| |
| // The initialization process should create new key files if the |
| // existing ones are not valid. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes() |
| // Return invalid public key data. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return([]byte("abc"), nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil). |
| AnyTimes() |
| // The initialization process should recreate the key files. |
| mockAPI.EXPECT().WriteFile(publicKeyFile, gomock.Any(), keyFilePerm). |
| Return(nil) |
| mockAPI.EXPECT().WriteFile(privateKeyFile, gomock.Any(), keyFilePerm). |
| Return(nil) |
| |
| // Return the correct public key data this time. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes() |
| |
| // Initialization process should create two default policy files. |
| gomock.InOrder( |
| mockAPI.EXPECT().FileExists(policyFile).Return(false).AnyTimes(), |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)), |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), policyFilePerm).Return(nil), |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes(), |
| ) |
| gomock.InOrder( |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(false).AnyTimes(), |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), cosDevicePolicyFilePerm).Return(nil), |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true).AnyTimes(), |
| ) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(nil); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestInitDevicePolicyNoOnDiskPolicy tests the scenario where InitDevicePolicy() is called |
| // with a nil InstanceConfig when one of device policy file missing. In this case, both files |
| // will be written. |
| func TestInitDevicePolicyNoOnDiskPolicy(t *testing.T) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public() |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| // Create fake policy. |
| policyBytes, _ := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| policyDir := filepath.Dir(policyFile) |
| mockAPI.EXPECT().MkdirAll(policyDir, policyFilePerm).Return(nil) |
| |
| // The initialization process should not create new key files if the |
| // existing ones are valid. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes() |
| // Return valid public/private key data. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil).AnyTimes() |
| |
| expectedInstanceConfig := getDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) |
| expectedPolicyBytes, expectedCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, expectedInstanceConfig) |
| |
| // As long as one policy file is missing, both need to be written. |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)).AnyTimes() |
| gomock.InOrder( |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes(), |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil).AnyTimes(), |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, expectedPolicyBytes)).Return(nil), |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes(), |
| mockAPI.EXPECT().ReadFile(policyFile).Return(expectedPolicyBytes, nil).AnyTimes(), |
| ) |
| gomock.InOrder( |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(false).AnyTimes(), |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| cosDevicePolicyFilePerm).Do(genInterceptPolicy(t, expectedCosDevicePolicyBytes)).Return(nil), |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true).AnyTimes(), |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(expectedCosDevicePolicyBytes, nil).AnyTimes(), |
| ) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(nil); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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 mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public() |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| // Create fake policy. |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| policyDir := filepath.Dir(policyFile) |
| mockAPI.EXPECT().MkdirAll(policyDir, policyFilePerm).Return(nil) |
| |
| // The initialization process should not create new key files if the |
| // existing ones are valid. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes() |
| // Return valid public/private key data. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil).AnyTimes() |
| |
| // Initialization process should not create default policy files if the |
| // existing policy files are valid. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)).AnyTimes() |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil).AnyTimes() |
| |
| newInstanceConfig := getDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) |
| newPolicyBytes, newCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, newInstanceConfig) |
| |
| // Expect the policy files to be written. |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, newPolicyBytes)).Return(nil) |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, newCosDevicePolicyBytes)).Return(nil) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(&pb.InstanceConfig{}); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestInitDevicePolicyWithBasePolicy tests the InitDevicePolicy() function when a custom |
| // base policy is specified. |
| func TestInitDevicePolicyWithBasePolicy(t *testing.T) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public() |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| // Create fake policy. |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| policyDir := filepath.Dir(policyFile) |
| mockAPI.EXPECT().MkdirAll(policyDir, policyFilePerm).Return(nil) |
| |
| // The initialization process should not create new key files if the |
| // existing ones are valid. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes() |
| // Return valid public/private key data. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil).AnyTimes() |
| |
| // Initialization process should not create policy files if the |
| // existing policy files are valid. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)).AnyTimes() |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil).AnyTimes() |
| |
| // Use custom base policy. |
| newInstanceConfig := getDefaultInstanceConfigFromBase( |
| &pb.InstanceConfig{ |
| TargetVersionPrefix: proto.String("7100."), |
| RebootAfterUpdate: proto.Bool(true), |
| }) |
| newPolicyBytes, newCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, newInstanceConfig) |
| |
| // Expect the policy to be written. |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, newPolicyBytes)).Return(nil) |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| cosDevicePolicyFilePerm).Do(genInterceptPolicy(t, newCosDevicePolicyBytes)).Return(nil) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(newInstanceConfig); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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 private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public() |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| // Create mock on-disk device policy. |
| currentConfig := &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String("8000."), |
| RebootAfterUpdate: proto.Bool(true), |
| UpdateScatterSeconds: proto.Int64(10), |
| } |
| currentConfig = getDefaultInstanceConfigFromBase(currentConfig) |
| currentPolicyBytes, currentCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, currentConfig) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| mockAPI.EXPECT().MkdirAll(filepath.Dir(policyFile), policyFilePerm).Return(nil) |
| // The initialization process should not create new key files if the |
| // existing ones are valid. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes() |
| // Return valid public/private key data. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil).AnyTimes() |
| |
| // Return the mocked on-disk device policy. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().ReadFile(policyFile).Return(currentPolicyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(currentCosDevicePolicyBytes, nil).AnyTimes() |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(nil); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestInitDevicePolicyWithNilBasePolicyAndNoCosDevicePolicyOnDisk tests that when baseConfig is |
| // nil and there is no COS policy file on disk, both ChromeOS device policy and COS policy |
| // should be populated using default. |
| func TestInitDevicePolicyWithNilBasePolicyAndNoCosDevicePolicyOnDisk(t *testing.T) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public() |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| // Create mock on-disk device policy. |
| currentConfig := &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String("8000."), |
| RebootAfterUpdate: proto.Bool(true), |
| UpdateScatterSeconds: proto.Int64(10), |
| } |
| currentConfig = getDefaultInstanceConfigFromBase(currentConfig) |
| currentPolicyBytes, _ := generateFakePolicyBytes(t, privateKey, currentConfig) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Make sure the initialization process ensures that the policy |
| // directory is present. |
| mockAPI.EXPECT().MkdirAll(filepath.Dir(policyFile), policyFilePerm).Return(nil) |
| // The initialization process should not create new key files if the |
| // existing ones are valid. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true).AnyTimes() |
| // Return valid public/private key data. |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil).AnyTimes() |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil).AnyTimes() |
| |
| // Return the mocked on-disk device policy. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true).AnyTimes() |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(false).AnyTimes() |
| mockAPI.EXPECT().ReadFile(policyFile).Return(currentPolicyBytes, nil).AnyTimes() |
| |
| // Expect both policy files to be written with default value. |
| defaultInstanceConfig := getDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) |
| defaultPolicyBytes, defaultCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, defaultInstanceConfig) |
| |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)).AnyTimes() |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, defaultPolicyBytes)).Return(nil) |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| cosDevicePolicyFilePerm).Do(genInterceptPolicy(t, defaultCosDevicePolicyBytes)).Return(nil) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.InitDevicePolicy(nil); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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 mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Create fake policy. |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| // The public/private keys should be read from file. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil) |
| |
| // Policy file doesn't exist, so a new file should be created. |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)) |
| mockAPI.EXPECT().FileExists(policyFile).Return(false) |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, policyBytes)).Return(nil) |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| cosDevicePolicyFilePerm).Do(genInterceptPolicy(t, cosDevicePolicyBytes)).Return(nil) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.SetInstanceConfig(instanceConfig); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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 mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeyBits) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Create fake policy. |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| // The public/private keys should be read from file. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil) |
| |
| // Policy files exist. |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)) |
| mockAPI.EXPECT().FileExists(policyFile).Return(true) |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil) |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil) |
| |
| // This is different than original instanceConfig. |
| newInstanceConfig := getDefaultInstanceConfigFromBase( |
| &pb.InstanceConfig{ |
| TargetVersionPrefix: proto.String("8011."), |
| RebootAfterUpdate: proto.Bool(true), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(false), |
| }, |
| }) |
| newPolicyBytes, newCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, newInstanceConfig) |
| |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, newPolicyBytes)).Return(nil) |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, newCosDevicePolicyBytes)).Return(nil) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.SetInstanceConfig(newInstanceConfig); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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 mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeyBits) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Create fake policy. |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| // The public/private keys should be read from file. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil) |
| |
| // Policy files exist. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true) |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil) |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil) |
| |
| // AtomicWriteFile not expected since there is no change in the instanceConfig. |
| manager := NewManager(mockAPI) |
| if err := manager.SetInstanceConfig(instanceConfig); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestSetInstanceConfig_EmptyConfig tests whether the SetInstanceConfig function sets |
| // correct default values when an empty InstanceConfig is passed. |
| func TestSetInstanceConfig_EmptyConfig(t *testing.T) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeyBits) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Create fake policy. Start with default instnace config. |
| defaultInstanceConfig := getDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, defaultInstanceConfig) |
| |
| // The public/private keys should be read from file. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil) |
| |
| // Policy file exist; simulate its read. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true) |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil) |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil) |
| |
| // This is just an empty instnace config. |
| emptyInstanceConfig := &pb.InstanceConfig{} |
| |
| // AtomicWriteFile not expected since empty config should resolve to the already present |
| // default config. |
| manager := NewManager(mockAPI) |
| if err := manager.SetInstanceConfig(emptyInstanceConfig); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestSetInstanceConfig_NilConfig tests whether the SetInstanceConfig function sets |
| // correct default values when an nil InstnaceConfig is passed. |
| func TestSetInstanceConfig_NilConfig(t *testing.T) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeyBits) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Create fake policy. Start with default instnace config. |
| defaultInstanceConfig := getDefaultInstanceConfigFromBase(&pb.InstanceConfig{}) |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, defaultInstanceConfig) |
| |
| // The public/private keys should be read from file. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil) |
| |
| // Policy file exist; simulate its read. |
| mockAPI.EXPECT().FileExists(policyFile).Return(true) |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil) |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil) |
| |
| // AtomicWriteFile not expected since empty config should resolve to the already present |
| // default config. |
| manager := NewManager(mockAPI) |
| if err := manager.SetInstanceConfig(nil); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // TestSetInstanceConfig_RemoveConfig tests whether the SetInstanceConfig function sets |
| // correct default values for a removed config option. |
| func TestSetInstanceConfig_RemoveConfig(t *testing.T) { |
| // Create mock private/public keys. |
| privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeyBits) |
| if err != nil { |
| t.Fatal(err) |
| } |
| publicKey := privateKey.Public().(*rsa.PublicKey) |
| |
| // Marshal the keys. |
| publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) |
| if err != nil { |
| t.Fatal(err) |
| } |
| privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
| |
| mockCtrl := gomock.NewController(t) |
| defer mockCtrl.Finish() |
| mockAPI := mocksysapi.NewMockAPIHandler(mockCtrl) |
| |
| // Create fake policy. |
| policyBytes, cosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, instanceConfig) |
| |
| // The public/private keys should be read from file. |
| mockAPI.EXPECT().FileExists(privateKeyFile).Return(true) |
| mockAPI.EXPECT().FileExists(publicKeyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(publicKeyFile).Return(publicKeyBytes, nil) |
| mockAPI.EXPECT().ReadFile(privateKeyFile).Return(privateKeyBytes, nil) |
| |
| // Policy file exist; simulate its read. |
| mockAPI.EXPECT().GetUnixTimestamp().Return(int64(0)) |
| mockAPI.EXPECT().FileExists(policyFile).Return(true) |
| mockAPI.EXPECT().FileExists(cosDevicePolicyFile).Return(true) |
| mockAPI.EXPECT().ReadFile(policyFile).Return(policyBytes, nil) |
| mockAPI.EXPECT().ReadFile(cosDevicePolicyFile).Return(cosDevicePolicyBytes, nil) |
| |
| // Note that UpdateScatterSeconds is not specified. |
| newInstanceConfig := &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(true), |
| TargetVersionPrefix: proto.String("8099."), |
| RebootAfterUpdate: proto.Bool(false), |
| 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(true), |
| TargetVersionPrefix: proto.String("8099."), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(33), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| } |
| expectedPolicyBytes, expectedCosDevicePolicyBytes := generateFakePolicyBytes(t, privateKey, expectedInstanceConfig) |
| |
| mockAPI.EXPECT().AtomicWriteFile(policyFile, gomock.Any(), |
| policyFilePerm).Do(genInterceptPolicy(t, expectedPolicyBytes)).Return(nil) |
| mockAPI.EXPECT().AtomicWriteFile(cosDevicePolicyFile, gomock.Any(), |
| cosDevicePolicyFilePerm).Do(genInterceptPolicy(t, expectedCosDevicePolicyBytes)).Return(nil) |
| |
| manager := NewManager(mockAPI) |
| if err := manager.SetInstanceConfig(newInstanceConfig); err != nil { |
| t.Error(err) |
| } |
| } |
| |
| // 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), |
| TargetVersionPrefix: proto.String(""), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(33), |
| 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, |
| }, |
| { |
| "BaseConfigWithCustomTargetVersionPrefix", |
| &pb.InstanceConfig{ |
| TargetVersionPrefix: proto.String("1.2.3"), |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String("1.2.3"), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(33), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(false), |
| LoggingEnabled: proto.Bool(false), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "BaseConfigWithMetricsEnabled", |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(true), |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(true), |
| TargetVersionPrefix: proto.String(""), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(33), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(false), |
| LoggingEnabled: proto.Bool(false), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "BaseConfigWithUpdateScatterSeconds", |
| &pb.InstanceConfig{ |
| UpdateScatterSeconds: proto.Int64(99), |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String(""), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(false), |
| LoggingEnabled: proto.Bool(false), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "BaseConfigWithMultipleFields", |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(true), |
| TargetVersionPrefix: proto.String("1.2.3"), |
| UpdateScatterSeconds: proto.Int64(99), |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(true), |
| TargetVersionPrefix: proto.String("1.2.3"), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(false), |
| LoggingEnabled: proto.Bool(false), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "BaseConfigEnablingLoggingMissingMonitoring", |
| &pb.InstanceConfig{ |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| }, |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String(""), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "BaseConfigEnforcedNotEnableLoggingMonitoring", |
| &pb.InstanceConfig{ |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(false), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String(""), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(false), |
| MonitoringEnabled: proto.Bool(false), |
| }, |
| }, |
| }, |
| { |
| "BaseConfigEnableLoggingAndMonitoring", |
| &pb.InstanceConfig{ |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(true), |
| }, |
| }, |
| &pb.InstanceConfig{ |
| MetricsEnabled: proto.Bool(false), |
| TargetVersionPrefix: proto.String(""), |
| RebootAfterUpdate: proto.Bool(false), |
| UpdateScatterSeconds: proto.Int64(99), |
| HealthMonitorConfig: &pb.HealthMonitorConfig{ |
| Enforced: proto.Bool(true), |
| LoggingEnabled: proto.Bool(true), |
| MonitoringEnabled: proto.Bool(true), |
| }, |
| }, |
| }, |
| } |
| |
| for _, test := range tests { |
| generatedConfig := getDefaultInstanceConfigFromBase(test.baseConfig) |
| if !proto.Equal(generatedConfig, test.expectedConfig) { |
| t.Errorf("In test %s, got %s, expected %s", |
| test.name, |
| proto.MarshalTextString(generatedConfig), |
| proto.MarshalTextString(test.expectedConfig)) |
| } |
| } |
| } |