github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/java/app_test.go (about)

     1  // Copyright 2017 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  
    15  package java
    16  
    17  import (
    18  	"android/soong/android"
    19  	"fmt"
    20  	"reflect"
    21  	"sort"
    22  	"strings"
    23  	"testing"
    24  )
    25  
    26  var (
    27  	resourceFiles = []string{
    28  		"res/layout/layout.xml",
    29  		"res/values/strings.xml",
    30  		"res/values-en-rUS/strings.xml",
    31  	}
    32  
    33  	compiledResourceFiles = []string{
    34  		"aapt2/res/layout_layout.xml.flat",
    35  		"aapt2/res/values_strings.arsc.flat",
    36  		"aapt2/res/values-en-rUS_strings.arsc.flat",
    37  	}
    38  )
    39  
    40  func testAppContext(config android.Config, bp string, fs map[string][]byte) *android.TestContext {
    41  	appFS := map[string][]byte{}
    42  	for k, v := range fs {
    43  		appFS[k] = v
    44  	}
    45  
    46  	for _, file := range resourceFiles {
    47  		appFS[file] = nil
    48  	}
    49  
    50  	return testContext(config, bp, appFS)
    51  }
    52  
    53  func testApp(t *testing.T, bp string) *android.TestContext {
    54  	config := testConfig(nil)
    55  
    56  	ctx := testAppContext(config, bp, nil)
    57  
    58  	run(t, ctx, config)
    59  
    60  	return ctx
    61  }
    62  
    63  func TestApp(t *testing.T) {
    64  	for _, moduleType := range []string{"android_app", "android_library"} {
    65  		t.Run(moduleType, func(t *testing.T) {
    66  			ctx := testApp(t, moduleType+` {
    67  					name: "foo",
    68  					srcs: ["a.java"],
    69  				}
    70  			`)
    71  
    72  			foo := ctx.ModuleForTests("foo", "android_common")
    73  
    74  			expectedLinkImplicits := []string{"AndroidManifest.xml"}
    75  
    76  			frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
    77  			expectedLinkImplicits = append(expectedLinkImplicits,
    78  				frameworkRes.Output("package-res.apk").Output.String())
    79  
    80  			// Test the mapping from input files to compiled output file names
    81  			compile := foo.Output(compiledResourceFiles[0])
    82  			if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
    83  				t.Errorf("expected aapt2 compile inputs expected:\n  %#v\n got:\n  %#v",
    84  					resourceFiles, compile.Inputs.Strings())
    85  			}
    86  
    87  			compiledResourceOutputs := compile.Outputs.Strings()
    88  			sort.Strings(compiledResourceOutputs)
    89  
    90  			expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
    91  
    92  			list := foo.Output("aapt2/res.list")
    93  			expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
    94  
    95  			// Check that the link rule uses
    96  			res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
    97  			if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
    98  				t.Errorf("expected aapt2 link implicits expected:\n  %#v\n got:\n  %#v",
    99  					expectedLinkImplicits, res.Implicits.Strings())
   100  			}
   101  		})
   102  	}
   103  }
   104  
   105  var testEnforceRROTests = []struct {
   106  	name                       string
   107  	enforceRROTargets          []string
   108  	enforceRROExcludedOverlays []string
   109  	fooOverlayFiles            []string
   110  	fooRRODirs                 []string
   111  	barOverlayFiles            []string
   112  	barRRODirs                 []string
   113  }{
   114  	{
   115  		name:                       "no RRO",
   116  		enforceRROTargets:          nil,
   117  		enforceRROExcludedOverlays: nil,
   118  		fooOverlayFiles: []string{
   119  			"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
   120  			"device/vendor/blah/overlay/foo/res/values/strings.xml",
   121  		},
   122  		fooRRODirs: nil,
   123  		barOverlayFiles: []string{
   124  			"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
   125  			"device/vendor/blah/overlay/bar/res/values/strings.xml",
   126  		},
   127  		barRRODirs: nil,
   128  	},
   129  	{
   130  		name:                       "enforce RRO on foo",
   131  		enforceRROTargets:          []string{"foo"},
   132  		enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
   133  		fooOverlayFiles: []string{
   134  			"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
   135  		},
   136  		fooRRODirs: []string{
   137  			"device/vendor/blah/overlay/foo/res",
   138  		},
   139  		barOverlayFiles: []string{
   140  			"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
   141  			"device/vendor/blah/overlay/bar/res/values/strings.xml",
   142  		},
   143  		barRRODirs: nil,
   144  	},
   145  	{
   146  		name:                       "enforce RRO on all",
   147  		enforceRROTargets:          []string{"*"},
   148  		enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
   149  		fooOverlayFiles: []string{
   150  			"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
   151  		},
   152  		fooRRODirs: []string{
   153  			"device/vendor/blah/overlay/foo/res",
   154  		},
   155  		barOverlayFiles: []string{
   156  			"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
   157  		},
   158  		barRRODirs: []string{
   159  			"device/vendor/blah/overlay/bar/res",
   160  		},
   161  	},
   162  }
   163  
   164  func TestEnforceRRO(t *testing.T) {
   165  	resourceOverlays := []string{
   166  		"device/vendor/blah/overlay",
   167  		"device/vendor/blah/overlay2",
   168  		"device/vendor/blah/static_overlay",
   169  	}
   170  
   171  	fs := map[string][]byte{
   172  		"foo/res/res/values/strings.xml":                               nil,
   173  		"bar/res/res/values/strings.xml":                               nil,
   174  		"device/vendor/blah/overlay/foo/res/values/strings.xml":        nil,
   175  		"device/vendor/blah/overlay/bar/res/values/strings.xml":        nil,
   176  		"device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
   177  		"device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
   178  		"device/vendor/blah/overlay2/res/values/strings.xml":           nil,
   179  	}
   180  
   181  	bp := `
   182  			android_app {
   183  				name: "foo",
   184  				resource_dirs: ["foo/res"],
   185  			}
   186  
   187  			android_app {
   188  				name: "bar",
   189  				resource_dirs: ["bar/res"],
   190  			}
   191  		`
   192  
   193  	for _, testCase := range testEnforceRROTests {
   194  		t.Run(testCase.name, func(t *testing.T) {
   195  			config := testConfig(nil)
   196  			config.TestProductVariables.ResourceOverlays = &resourceOverlays
   197  			if testCase.enforceRROTargets != nil {
   198  				config.TestProductVariables.EnforceRROTargets = &testCase.enforceRROTargets
   199  			}
   200  			if testCase.enforceRROExcludedOverlays != nil {
   201  				config.TestProductVariables.EnforceRROExcludedOverlays = &testCase.enforceRROExcludedOverlays
   202  			}
   203  
   204  			ctx := testAppContext(config, bp, fs)
   205  			run(t, ctx, config)
   206  
   207  			getOverlays := func(moduleName string) ([]string, []string) {
   208  				module := ctx.ModuleForTests(moduleName, "android_common")
   209  				overlayCompiledPaths := module.Output("aapt2/overlay.list").Inputs.Strings()
   210  
   211  				var overlayFiles []string
   212  				for _, o := range overlayCompiledPaths {
   213  					overlayFiles = append(overlayFiles, module.Output(o).Inputs.Strings()...)
   214  				}
   215  
   216  				rroDirs := module.Module().(*AndroidApp).rroDirs.Strings()
   217  
   218  				return overlayFiles, rroDirs
   219  			}
   220  
   221  			fooOverlayFiles, fooRRODirs := getOverlays("foo")
   222  			barOverlayFiles, barRRODirs := getOverlays("bar")
   223  
   224  			if !reflect.DeepEqual(fooOverlayFiles, testCase.fooOverlayFiles) {
   225  				t.Errorf("expected foo overlay files:\n  %#v\n got:\n  %#v",
   226  					testCase.fooOverlayFiles, fooOverlayFiles)
   227  			}
   228  			if !reflect.DeepEqual(fooRRODirs, testCase.fooRRODirs) {
   229  				t.Errorf("expected foo rroDirs:  %#v\n got:\n  %#v",
   230  					testCase.fooRRODirs, fooRRODirs)
   231  			}
   232  
   233  			if !reflect.DeepEqual(barOverlayFiles, testCase.barOverlayFiles) {
   234  				t.Errorf("expected bar overlay files:\n  %#v\n got:\n  %#v",
   235  					testCase.barOverlayFiles, barOverlayFiles)
   236  			}
   237  			if !reflect.DeepEqual(barRRODirs, testCase.barRRODirs) {
   238  				t.Errorf("expected bar rroDirs:  %#v\n got:\n  %#v",
   239  					testCase.barRRODirs, barRRODirs)
   240  			}
   241  
   242  		})
   243  	}
   244  }
   245  
   246  func TestAppSdkVersion(t *testing.T) {
   247  	testCases := []struct {
   248  		name                  string
   249  		sdkVersion            string
   250  		platformSdkInt        int
   251  		platformSdkCodename   string
   252  		platformSdkFinal      bool
   253  		expectedMinSdkVersion string
   254  	}{
   255  		{
   256  			name:                  "current final SDK",
   257  			sdkVersion:            "current",
   258  			platformSdkInt:        27,
   259  			platformSdkCodename:   "REL",
   260  			platformSdkFinal:      true,
   261  			expectedMinSdkVersion: "27",
   262  		},
   263  		{
   264  			name:                  "current non-final SDK",
   265  			sdkVersion:            "current",
   266  			platformSdkInt:        27,
   267  			platformSdkCodename:   "OMR1",
   268  			platformSdkFinal:      false,
   269  			expectedMinSdkVersion: "OMR1",
   270  		},
   271  		{
   272  			name:                  "default final SDK",
   273  			sdkVersion:            "",
   274  			platformSdkInt:        27,
   275  			platformSdkCodename:   "REL",
   276  			platformSdkFinal:      true,
   277  			expectedMinSdkVersion: "27",
   278  		},
   279  		{
   280  			name:                  "default non-final SDK",
   281  			sdkVersion:            "",
   282  			platformSdkInt:        27,
   283  			platformSdkCodename:   "OMR1",
   284  			platformSdkFinal:      false,
   285  			expectedMinSdkVersion: "OMR1",
   286  		},
   287  		{
   288  			name:                  "14",
   289  			sdkVersion:            "14",
   290  			expectedMinSdkVersion: "14",
   291  		},
   292  	}
   293  
   294  	for _, moduleType := range []string{"android_app", "android_library"} {
   295  		for _, test := range testCases {
   296  			t.Run(moduleType+" "+test.name, func(t *testing.T) {
   297  				bp := fmt.Sprintf(`%s {
   298  					name: "foo",
   299  					srcs: ["a.java"],
   300  					sdk_version: "%s",
   301  				}`, moduleType, test.sdkVersion)
   302  
   303  				config := testConfig(nil)
   304  				config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
   305  				config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
   306  				config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
   307  
   308  				ctx := testAppContext(config, bp, nil)
   309  
   310  				run(t, ctx, config)
   311  
   312  				foo := ctx.ModuleForTests("foo", "android_common")
   313  				link := foo.Output("package-res.apk")
   314  				linkFlags := strings.Split(link.Args["flags"], " ")
   315  				min := android.IndexList("--min-sdk-version", linkFlags)
   316  				target := android.IndexList("--target-sdk-version", linkFlags)
   317  
   318  				if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
   319  					t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
   320  				}
   321  
   322  				gotMinSdkVersion := linkFlags[min+1]
   323  				gotTargetSdkVersion := linkFlags[target+1]
   324  
   325  				if gotMinSdkVersion != test.expectedMinSdkVersion {
   326  					t.Errorf("incorrect --min-sdk-version, expected %q got %q",
   327  						test.expectedMinSdkVersion, gotMinSdkVersion)
   328  				}
   329  
   330  				if gotTargetSdkVersion != test.expectedMinSdkVersion {
   331  					t.Errorf("incorrect --target-sdk-version, expected %q got %q",
   332  						test.expectedMinSdkVersion, gotTargetSdkVersion)
   333  				}
   334  			})
   335  		}
   336  	}
   337  }