symbols_map_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright 2022 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "io/ioutil"
  17. "os"
  18. "path/filepath"
  19. "strings"
  20. "testing"
  21. "android/soong/cmd/symbols_map/symbols_map_proto"
  22. "google.golang.org/protobuf/encoding/prototext"
  23. "google.golang.org/protobuf/proto"
  24. )
  25. func Test_mergeProtos(t *testing.T) {
  26. type testFile struct {
  27. filename string
  28. contents *symbols_map_proto.Mapping
  29. missing bool
  30. }
  31. tests := []struct {
  32. name string
  33. inputs []testFile
  34. stripPrefix string
  35. writeIfChanged bool
  36. ignoreMissingFiles bool
  37. error string
  38. output *symbols_map_proto.Mappings
  39. }{
  40. {
  41. name: "empty",
  42. output: &symbols_map_proto.Mappings{},
  43. },
  44. {
  45. name: "merge",
  46. inputs: []testFile{
  47. {
  48. filename: "foo",
  49. contents: &symbols_map_proto.Mapping{
  50. Identifier: proto.String("foo"),
  51. Location: proto.String("symbols/foo"),
  52. Type: symbols_map_proto.Mapping_ELF.Enum(),
  53. },
  54. },
  55. {
  56. filename: "bar",
  57. contents: &symbols_map_proto.Mapping{
  58. Identifier: proto.String("bar"),
  59. Location: proto.String("symbols/bar"),
  60. Type: symbols_map_proto.Mapping_R8.Enum(),
  61. },
  62. },
  63. },
  64. output: &symbols_map_proto.Mappings{
  65. Mappings: []*symbols_map_proto.Mapping{
  66. {
  67. Identifier: proto.String("foo"),
  68. Location: proto.String("symbols/foo"),
  69. Type: symbols_map_proto.Mapping_ELF.Enum(),
  70. },
  71. {
  72. Identifier: proto.String("bar"),
  73. Location: proto.String("symbols/bar"),
  74. Type: symbols_map_proto.Mapping_R8.Enum(),
  75. },
  76. },
  77. },
  78. },
  79. {
  80. name: "strip prefix",
  81. inputs: []testFile{
  82. {
  83. filename: "foo",
  84. contents: &symbols_map_proto.Mapping{
  85. Identifier: proto.String("foo"),
  86. Location: proto.String("symbols/foo"),
  87. Type: symbols_map_proto.Mapping_ELF.Enum(),
  88. },
  89. },
  90. {
  91. filename: "bar",
  92. contents: &symbols_map_proto.Mapping{
  93. Identifier: proto.String("bar"),
  94. Location: proto.String("symbols/bar"),
  95. Type: symbols_map_proto.Mapping_R8.Enum(),
  96. },
  97. },
  98. },
  99. stripPrefix: "symbols/",
  100. output: &symbols_map_proto.Mappings{
  101. Mappings: []*symbols_map_proto.Mapping{
  102. {
  103. Identifier: proto.String("foo"),
  104. Location: proto.String("foo"),
  105. Type: symbols_map_proto.Mapping_ELF.Enum(),
  106. },
  107. {
  108. Identifier: proto.String("bar"),
  109. Location: proto.String("bar"),
  110. Type: symbols_map_proto.Mapping_R8.Enum(),
  111. },
  112. },
  113. },
  114. },
  115. {
  116. name: "missing",
  117. inputs: []testFile{
  118. {
  119. filename: "foo",
  120. contents: &symbols_map_proto.Mapping{
  121. Identifier: proto.String("foo"),
  122. Location: proto.String("symbols/foo"),
  123. Type: symbols_map_proto.Mapping_ELF.Enum(),
  124. },
  125. },
  126. {
  127. filename: "bar",
  128. missing: true,
  129. },
  130. },
  131. error: "no such file or directory",
  132. },
  133. {
  134. name: "ignore missing",
  135. inputs: []testFile{
  136. {
  137. filename: "foo",
  138. contents: &symbols_map_proto.Mapping{
  139. Identifier: proto.String("foo"),
  140. Location: proto.String("symbols/foo"),
  141. Type: symbols_map_proto.Mapping_ELF.Enum(),
  142. },
  143. },
  144. {
  145. filename: "bar",
  146. missing: true,
  147. },
  148. },
  149. ignoreMissingFiles: true,
  150. output: &symbols_map_proto.Mappings{
  151. Mappings: []*symbols_map_proto.Mapping{
  152. {
  153. Identifier: proto.String("foo"),
  154. Location: proto.String("symbols/foo"),
  155. Type: symbols_map_proto.Mapping_ELF.Enum(),
  156. },
  157. },
  158. },
  159. },
  160. }
  161. for _, tt := range tests {
  162. t.Run(tt.name, func(t *testing.T) {
  163. dir, err := os.MkdirTemp("", "test_mergeProtos")
  164. if err != nil {
  165. t.Fatalf("failed to create temporary directory: %s", err)
  166. }
  167. defer os.RemoveAll(dir)
  168. var inputs []string
  169. for _, in := range tt.inputs {
  170. path := filepath.Join(dir, in.filename)
  171. inputs = append(inputs, path)
  172. if !in.missing {
  173. err := writeTextProto(path, in.contents, false)
  174. if err != nil {
  175. t.Fatalf("failed to create input file %s: %s", path, err)
  176. }
  177. }
  178. }
  179. output := filepath.Join(dir, "out")
  180. err = mergeProtos(output, inputs, tt.stripPrefix, tt.writeIfChanged, tt.ignoreMissingFiles)
  181. if err != nil {
  182. if tt.error != "" {
  183. if !strings.Contains(err.Error(), tt.error) {
  184. t.Fatalf("expected error %q, got %s", tt.error, err.Error())
  185. }
  186. } else {
  187. t.Fatalf("unexpected error %q", err)
  188. }
  189. } else if tt.error != "" {
  190. t.Fatalf("missing error %q", tt.error)
  191. } else {
  192. data, err := ioutil.ReadFile(output)
  193. if err != nil {
  194. t.Fatalf("failed to read output file %s: %s", output, err)
  195. }
  196. var got symbols_map_proto.Mappings
  197. err = prototext.Unmarshal(data, &got)
  198. if err != nil {
  199. t.Fatalf("failed to unmarshal textproto %s: %s", output, err)
  200. }
  201. if !proto.Equal(tt.output, &got) {
  202. t.Fatalf("expected output %q, got %q", tt.output.String(), got.String())
  203. }
  204. }
  205. })
  206. }
  207. }