env_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package main
  5. import (
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "path/filepath"
  10. "testing"
  11. )
  12. func TestNdkRoot(t *testing.T) {
  13. home, err := ioutil.TempDir("", "gomobile-test-")
  14. if err != nil {
  15. t.Fatal(err)
  16. }
  17. homeorig := os.Getenv("ANDROID_HOME")
  18. os.Unsetenv("ANDROID_HOME")
  19. ndkhomeorig := os.Getenv("ANDROID_NDK_HOME")
  20. os.Unsetenv("ANDROID_NDK_HOME")
  21. defer func() {
  22. os.Setenv("ANDROID_HOME", homeorig)
  23. os.Setenv("ANDROID_NDK_HOME", ndkhomeorig)
  24. os.RemoveAll(home)
  25. }()
  26. makeMockNDK := func(path, version, platforms, abis string) string {
  27. dir := filepath.Join(home, path)
  28. if err := os.Mkdir(dir, 0755); err != nil {
  29. t.Fatalf("couldn't mkdir %q", dir)
  30. }
  31. propertiesPath := filepath.Join(dir, "source.properties")
  32. propertiesData := []byte("Pkg.Revision = " + version)
  33. if err := os.WriteFile(propertiesPath, propertiesData, 0644); err != nil {
  34. t.Fatalf("couldn't write source.properties: %v", err)
  35. }
  36. metaDir := filepath.Join(dir, "meta")
  37. if err := os.Mkdir(metaDir, 0755); err != nil {
  38. t.Fatalf("couldn't mkdir %q", metaDir)
  39. }
  40. platformsPath := filepath.Join(metaDir, "platforms.json")
  41. platformsData := []byte(platforms)
  42. if err := os.WriteFile(platformsPath, platformsData, 0644); err != nil {
  43. t.Fatalf("couldn't write platforms.json: %v", err)
  44. }
  45. abisPath := filepath.Join(metaDir, "abis.json")
  46. abisData := []byte(abis)
  47. if err := os.WriteFile(abisPath, abisData, 0644); err != nil {
  48. t.Fatalf("couldn't populate abis.json: %v", err)
  49. }
  50. return dir
  51. }
  52. t.Run("no NDK in the default location", func(t *testing.T) {
  53. os.Setenv("ANDROID_HOME", home)
  54. defer os.Unsetenv("ANDROID_HOME")
  55. if ndk, err := ndkRoot(); err == nil {
  56. t.Errorf("expected error but got %q", ndk)
  57. }
  58. })
  59. t.Run("NDK location is set but is wrong", func(t *testing.T) {
  60. os.Setenv("ANDROID_NDK_HOME", filepath.Join(home, "no-such-path"))
  61. defer os.Unsetenv("ANDROID_NDK_HOME")
  62. if ndk, err := ndkRoot(); err == nil {
  63. t.Errorf("expected error but got %q", ndk)
  64. }
  65. })
  66. t.Run("Two NDKs installed", func(t *testing.T) {
  67. // Default path for pre-side-by-side NDKs.
  68. sdkNDK := makeMockNDK("ndk-bundle", "fake-version", `{"min":16,"max":32}`, "{}")
  69. defer os.RemoveAll(sdkNDK)
  70. // Arbitrary location for testing ANDROID_NDK_HOME.
  71. envNDK := makeMockNDK("custom-location", "fake-version", `{"min":16,"max":32}`, "{}")
  72. // ANDROID_NDK_HOME is sufficient.
  73. os.Setenv("ANDROID_NDK_HOME", envNDK)
  74. if ndk, err := ndkRoot(); ndk != envNDK {
  75. t.Errorf("got (%q, %v) want (%q, nil)", ndk, err, envNDK)
  76. }
  77. // ANDROID_NDK_HOME takes precedence over ANDROID_HOME.
  78. os.Setenv("ANDROID_HOME", home)
  79. if ndk, err := ndkRoot(); ndk != envNDK {
  80. t.Errorf("got (%q, %v) want (%q, nil)", ndk, err, envNDK)
  81. }
  82. // ANDROID_NDK_HOME is respected even if there is no NDK there.
  83. os.RemoveAll(envNDK)
  84. if ndk, err := ndkRoot(); err == nil {
  85. t.Errorf("expected error but got %q", ndk)
  86. }
  87. // ANDROID_HOME is used if ANDROID_NDK_HOME is not set.
  88. os.Unsetenv("ANDROID_NDK_HOME")
  89. if ndk, err := ndkRoot(); ndk != sdkNDK {
  90. t.Errorf("got (%q, %v) want (%q, nil)", ndk, err, envNDK)
  91. }
  92. })
  93. t.Run("Modern 'side-by-side' NDK selection", func(t *testing.T) {
  94. defer func() {
  95. buildAndroidAPI = minAndroidAPI
  96. }()
  97. ndkForest := filepath.Join(home, "ndk")
  98. if err := os.Mkdir(ndkForest, 0755); err != nil {
  99. t.Fatalf("couldn't mkdir %q", ndkForest)
  100. }
  101. path := filepath.Join("ndk", "newer")
  102. platforms := `{"min":19,"max":32}`
  103. abis := `{"arm64-v8a": {}, "armeabi-v7a": {}, "x86_64": {}}`
  104. version := "17.2.0"
  105. newerNDK := makeMockNDK(path, version, platforms, abis)
  106. path = filepath.Join("ndk", "older")
  107. platforms = `{"min":16,"max":31}`
  108. abis = `{"arm64-v8a": {}, "armeabi-v7a": {}, "x86": {}}`
  109. version = "17.1.0"
  110. olderNDK := makeMockNDK(path, version, platforms, abis)
  111. testCases := []struct {
  112. api int
  113. targets []targetInfo
  114. wantNDKRoot string
  115. }{
  116. {15, nil, ""},
  117. {16, nil, olderNDK},
  118. {16, []targetInfo{{"android", "arm"}}, olderNDK},
  119. {16, []targetInfo{{"android", "arm"}, {"android", "arm64"}}, olderNDK},
  120. {16, []targetInfo{{"android", "x86_64"}}, ""},
  121. {19, nil, newerNDK},
  122. {19, []targetInfo{{"android", "arm"}}, newerNDK},
  123. {19, []targetInfo{{"android", "arm"}, {"android", "arm64"}, {"android", "386"}}, olderNDK},
  124. {32, nil, newerNDK},
  125. {32, []targetInfo{{"android", "arm"}}, newerNDK},
  126. {32, []targetInfo{{"android", "386"}}, ""},
  127. }
  128. for i, tc := range testCases {
  129. t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
  130. buildAndroidAPI = tc.api
  131. ndk, err := ndkRoot(tc.targets...)
  132. if len(tc.wantNDKRoot) != 0 {
  133. if ndk != tc.wantNDKRoot || err != nil {
  134. t.Errorf("got (%q, %v), want (%q, nil)", ndk, err, tc.wantNDKRoot)
  135. }
  136. } else if err == nil {
  137. t.Error("expected error")
  138. }
  139. })
  140. }
  141. })
  142. }