Home | History | Annotate | Download | only in android
      1 // Copyright 2016 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 android
     16 
     17 import (
     18 	"io/ioutil"
     19 	"os"
     20 	"testing"
     21 
     22 	"github.com/google/blueprint"
     23 )
     24 
     25 var prebuiltsTests = []struct {
     26 	name     string
     27 	modules  string
     28 	prebuilt bool
     29 }{
     30 	{
     31 		name: "no prebuilt",
     32 		modules: `
     33 			source {
     34 				name: "bar",
     35 			}`,
     36 		prebuilt: false,
     37 	},
     38 	{
     39 		name: "no source prebuilt not preferred",
     40 		modules: `
     41 			prebuilt {
     42 				name: "bar",
     43 				prefer: false,
     44 				srcs: ["prebuilt"],
     45 			}`,
     46 		prebuilt: true,
     47 	},
     48 	{
     49 		name: "no source prebuilt preferred",
     50 		modules: `
     51 			prebuilt {
     52 				name: "bar",
     53 				prefer: true,
     54 				srcs: ["prebuilt"],
     55 			}`,
     56 		prebuilt: true,
     57 	},
     58 	{
     59 		name: "prebuilt not preferred",
     60 		modules: `
     61 			source {
     62 				name: "bar",
     63 			}
     64 			
     65 			prebuilt {
     66 				name: "bar",
     67 				prefer: false,
     68 				srcs: ["prebuilt"],
     69 			}`,
     70 		prebuilt: false,
     71 	},
     72 	{
     73 		name: "prebuilt preferred",
     74 		modules: `
     75 			source {
     76 				name: "bar",
     77 			}
     78 			
     79 			prebuilt {
     80 				name: "bar",
     81 				prefer: true,
     82 				srcs: ["prebuilt"],
     83 			}`,
     84 		prebuilt: true,
     85 	},
     86 	{
     87 		name: "prebuilt no file not preferred",
     88 		modules: `
     89 			source {
     90 				name: "bar",
     91 			}
     92 			
     93 			prebuilt {
     94 				name: "bar",
     95 				prefer: false,
     96 			}`,
     97 		prebuilt: false,
     98 	},
     99 	{
    100 		name: "prebuilt no file preferred",
    101 		modules: `
    102 			source {
    103 				name: "bar",
    104 			}
    105 			
    106 			prebuilt {
    107 				name: "bar",
    108 				prefer: true,
    109 			}`,
    110 		prebuilt: false,
    111 	},
    112 }
    113 
    114 func TestPrebuilts(t *testing.T) {
    115 	buildDir, err := ioutil.TempDir("", "soong_prebuilt_test")
    116 	if err != nil {
    117 		t.Fatal(err)
    118 	}
    119 	defer os.RemoveAll(buildDir)
    120 
    121 	config := TestConfig(buildDir)
    122 
    123 	for _, test := range prebuiltsTests {
    124 		t.Run(test.name, func(t *testing.T) {
    125 			ctx := NewContext()
    126 			ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
    127 			ctx.RegisterModuleType("source", newSourceModule)
    128 			ctx.MockFileSystem(map[string][]byte{
    129 				"Blueprints": []byte(`
    130 					source {
    131 						name: "foo",
    132 						deps: ["bar"],
    133 					}
    134 					` + test.modules),
    135 			})
    136 
    137 			_, errs := ctx.ParseBlueprintsFiles("Blueprints")
    138 			fail(t, errs)
    139 			_, errs = ctx.PrepareBuildActions(config)
    140 			fail(t, errs)
    141 
    142 			foo := findModule(ctx, "foo")
    143 			if foo == nil {
    144 				t.Fatalf("failed to find module foo")
    145 			}
    146 
    147 			var dependsOnSourceModule, dependsOnPrebuiltModule bool
    148 			ctx.VisitDirectDeps(foo, func(m blueprint.Module) {
    149 				if _, ok := m.(*sourceModule); ok {
    150 					dependsOnSourceModule = true
    151 				}
    152 				if p, ok := m.(*prebuiltModule); ok {
    153 					dependsOnPrebuiltModule = true
    154 					if !p.Prebuilt().Properties.UsePrebuilt {
    155 						t.Errorf("dependency on prebuilt module not marked used")
    156 					}
    157 				}
    158 			})
    159 
    160 			if test.prebuilt {
    161 				if !dependsOnPrebuiltModule {
    162 					t.Errorf("doesn't depend on prebuilt module")
    163 				}
    164 
    165 				if dependsOnSourceModule {
    166 					t.Errorf("depends on source module")
    167 				}
    168 			} else {
    169 				if dependsOnPrebuiltModule {
    170 					t.Errorf("depends on prebuilt module")
    171 				}
    172 
    173 				if !dependsOnSourceModule {
    174 					t.Errorf("doens't depend on source module")
    175 				}
    176 			}
    177 		})
    178 	}
    179 }
    180 
    181 type prebuiltModule struct {
    182 	ModuleBase
    183 	prebuilt Prebuilt
    184 }
    185 
    186 func newPrebuiltModule() (blueprint.Module, []interface{}) {
    187 	m := &prebuiltModule{}
    188 	return InitAndroidModule(m, &m.prebuilt.Properties)
    189 }
    190 
    191 func (p *prebuiltModule) Name() string {
    192 	return p.prebuilt.Name(p.ModuleBase.Name())
    193 }
    194 
    195 func (p *prebuiltModule) DepsMutator(ctx BottomUpMutatorContext) {
    196 }
    197 
    198 func (p *prebuiltModule) GenerateAndroidBuildActions(ModuleContext) {
    199 }
    200 
    201 func (p *prebuiltModule) Prebuilt() *Prebuilt {
    202 	return &p.prebuilt
    203 }
    204 
    205 type sourceModule struct {
    206 	ModuleBase
    207 	properties struct {
    208 		Deps []string
    209 	}
    210 	dependsOnSourceModule, dependsOnPrebuiltModule bool
    211 }
    212 
    213 func newSourceModule() (blueprint.Module, []interface{}) {
    214 	m := &sourceModule{}
    215 	return InitAndroidModule(m, &m.properties)
    216 }
    217 
    218 func (s *sourceModule) DepsMutator(ctx BottomUpMutatorContext) {
    219 	for _, d := range s.properties.Deps {
    220 		ctx.AddDependency(ctx.Module(), nil, d)
    221 	}
    222 }
    223 
    224 func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
    225 }
    226 
    227 func findModule(ctx *blueprint.Context, name string) blueprint.Module {
    228 	var ret blueprint.Module
    229 	ctx.VisitAllModules(func(m blueprint.Module) {
    230 		if ctx.ModuleName(m) == name {
    231 			ret = m
    232 		}
    233 	})
    234 	return ret
    235 }
    236 
    237 func fail(t *testing.T, errs []error) {
    238 	if len(errs) > 0 {
    239 		for _, err := range errs {
    240 			t.Error(err)
    241 		}
    242 		t.FailNow()
    243 	}
    244 }
    245