| // Copyright 2022 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. |
| |
| // Unit tests for the imgstatus implementation. |
| package imgstatus |
| |
| import ( |
| "os" |
| "policy-manager/pkg/sysapi" |
| "policy-manager/protos" |
| "reflect" |
| "strings" |
| "testing" |
| |
| "github.com/golang/protobuf/proto" |
| ) |
| |
| const ( |
| // Test LSB file. |
| testLSB = `CHROMEOS_AUSERVER=https://tools.google.com/service/update2 |
| CHROMEOS_BOARD_APPID={76E245CF-C0D0-444D-BA50-36739C18EB00} |
| CHROMEOS_DEVSERVER= |
| CHROMEOS_RELEASE_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1} |
| CHROMEOS_RELEASE_BOARD=lakitu-signed-prempkeys |
| CHROMEOS_RELEASE_BRANCH_NUMBER=0 |
| CHROMEOS_RELEASE_BUILD_NUMBER=16511 |
| CHROMEOS_RELEASE_BUILD_TYPE=Official Build |
| CHROMEOS_RELEASE_CHROME_MILESTONE=89 |
| CHROMEOS_RELEASE_DESCRIPTION=16511.0.0 (Official Build) dev-channel lakitu |
| CHROMEOS_RELEASE_NAME=Chrome OS |
| CHROMEOS_RELEASE_PATCH_NUMBER=0 |
| CHROMEOS_RELEASE_TRACK=dev-channel |
| CHROMEOS_RELEASE_VERSION=16511.0.0 |
| GOOGLE_RELEASE=16511.0.0 |
| HWID_OVERRIDE=LAKITU` |
| |
| testDevBuildLSB = ` |
| CHROMEOS_RELEASE_BOARD=lakitu |
| CHROMEOS_DEVSERVER=http://foo.google.com:8080 |
| GOOGLE_RELEASE=7520.3.2015_10_12_1443 |
| CHROMEOS_RELEASE_BUILD_NUMBER=7520 |
| CHROMEOS_RELEASE_BRANCH_NUMBER=3 |
| CHROMEOS_RELEASE_CHROME_MILESTONE=89 |
| CHROMEOS_RELEASE_PATCH_NUMBER=2015_10_12_1443 |
| CHROMEOS_RELEASE_TRACK=developer-build |
| CHROMEOS_RELEASE_DESCRIPTION=7520.3.2015_10_12_1443 (Developer Build) |
| CHROMEOS_RELEASE_NAME=Chromium OS |
| CHROMEOS_RELEASE_BUILD_TYPE=Developer Build |
| CHROMEOS_RELEASE_VERSION=7520.3.2015_10_12_1443 |
| CHROMEOS_AUSERVER=http://foo.google.com:8080/update` |
| |
| // Dummy instance ID. |
| testInstanceID = uint64(12031993) |
| tmpLsbFile = "/tmp/lsb-release" |
| tmpLsbFilePerm = os.FileMode(0644) |
| ) |
| |
| // TestParseKeyValuePairs tests that we can correctly parse /etc/lsb-release |
| // into a map. |
| func TestParseKeyValuePairs(t *testing.T) { |
| tests := []struct { |
| name string |
| want map[string]string |
| input string |
| }{ |
| { |
| "ParseLSBFile", |
| map[string]string{ |
| "CHROMEOS_AUSERVER": "https://tools.google.com/service/update2", |
| "CHROMEOS_BOARD_APPID": "{76E245CF-C0D0-444D-BA50-36739C18EB00}", |
| "CHROMEOS_DEVSERVER": "", |
| "CHROMEOS_RELEASE_APPID": "{90F229CE-83E2-4FAF-8479-E368A34938B1}", |
| "CHROMEOS_RELEASE_BOARD": "lakitu-signed-prempkeys", |
| "CHROMEOS_RELEASE_BRANCH_NUMBER": "0", |
| "CHROMEOS_RELEASE_BUILD_NUMBER": "16511", |
| "CHROMEOS_RELEASE_BUILD_TYPE": "Official Build", |
| "CHROMEOS_RELEASE_CHROME_MILESTONE": "89", |
| "CHROMEOS_RELEASE_DESCRIPTION": "16511.0.0 (Official Build) dev-channel lakitu", |
| "CHROMEOS_RELEASE_NAME": "Chrome OS", |
| "CHROMEOS_RELEASE_PATCH_NUMBER": "0", |
| "CHROMEOS_RELEASE_TRACK": "dev-channel", |
| "CHROMEOS_RELEASE_VERSION": "16511.0.0", |
| "GOOGLE_RELEASE": "16511.0.0", |
| "HWID_OVERRIDE": "LAKITU", |
| }, |
| testLSB, |
| }, |
| { |
| "PoorlyFormattedPairs", |
| map[string]string{ |
| "apple_A": "a", |
| "BAnaNA_b_": "b", |
| "cantaloupe": "", |
| }, |
| ` |
| apple_A= a |
| BAnaNA_b_ =b |
| cantaloupe= |
| `, |
| }, |
| } |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| mockReader := strings.NewReader(test.input) |
| pairs, err := parseKeyValuePairs(mockReader) |
| if err != nil { |
| t.Errorf("got unexpected error %v", err) |
| } else if !reflect.DeepEqual(pairs, test.want) { |
| t.Errorf("got %v, want %v", pairs, test.want) |
| } |
| }) |
| } |
| } |
| |
| // TestConvertOSReleaseChannel tests that we can correctly convert the string |
| // representation of release channel into the protobuf definition. |
| func TestConvertOSReleaseChannel(t *testing.T) { |
| tests := []struct { |
| name string |
| want protos.ReleaseChannel |
| input string |
| }{ |
| { |
| "DevChannelTest", |
| protos.ReleaseChannel_DEV, |
| "dev-channel", |
| }, |
| { |
| "BetaChannelTest", |
| protos.ReleaseChannel_BETA, |
| "beta-channel", |
| }, |
| { |
| "StableChannelTest", |
| protos.ReleaseChannel_STABLE, |
| "stable-channel", |
| }, |
| { |
| "DeveloperBuildTest", |
| protos.ReleaseChannel_RELEASE_CHANNEL_UNSPECIFIED, |
| "developer-build", |
| }, |
| { |
| "BadChannelTest", |
| protos.ReleaseChannel_RELEASE_CHANNEL_UNSPECIFIED, |
| "abc-chan", |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| result := convertOSReleaseChannel(test.input) |
| if !reflect.DeepEqual(test.want, result) { |
| t.Errorf("got %s, want %s", |
| result.String(), |
| test.want.String()) |
| } |
| }) |
| } |
| } |
| |
| // TestParseOSInfoFromLSB tests that we can correctly get the OS version and |
| // release channel from a lsb-release file. |
| func TestParseOSInfoFromLSB(t *testing.T) { |
| devChannel := protos.ReleaseChannel_DEV |
| unknownChannel := protos.ReleaseChannel_RELEASE_CHANNEL_UNSPECIFIED |
| |
| tests := []struct { |
| name string |
| want *protos.OSVersion |
| lsbContent string |
| expectErr bool |
| }{ |
| { |
| "GoodLSBFile", |
| &protos.OSVersion{ |
| VersionString: proto.String("16511.0.0"), |
| Milestone: proto.Uint32(uint32(89)), |
| Channel: &devChannel, |
| }, |
| testLSB, |
| false, |
| }, |
| { |
| "OnlyReleaseVersion", |
| &protos.OSVersion{ |
| VersionString: proto.String("16511.0.0"), |
| }, |
| "CHROMEOS_RELEASE_VERSION=16511.0.0", |
| false, |
| }, |
| { |
| "BadLSBFile", |
| &protos.OSVersion{}, |
| "", |
| false, |
| }, |
| { |
| "DevBuildLSBFile", |
| &protos.OSVersion{ |
| VersionString: proto.String("7520.3.2015_10_12_1443"), |
| Milestone: proto.Uint32(uint32(89)), |
| Channel: &unknownChannel, |
| }, |
| testDevBuildLSB, |
| false, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| sysapi.AtomicWriteFile(tmpLsbFile, []byte(test.lsbContent), tmpLsbFilePerm) |
| defer os.RemoveAll(tmpLsbFile) |
| |
| result, err := parseOSInfoFromLSB(tmpLsbFile) |
| |
| if err == nil && test.expectErr { |
| t.Errorf("test passed, want error") |
| } else if err == nil && !proto.Equal(test.want, result) { |
| t.Errorf("got %s, want %s", |
| result.String(), |
| test.want.String()) |
| } else if err != nil && !test.expectErr { |
| t.Errorf("got unexpected error %v", err) |
| } |
| }) |
| } |
| } |