env_test.go 4.9 KB

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