2018-05-26 01:30:04 +02:00
// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"android/soong/ui/build/paths"
)
var tmpDir string
var origPATH string
func TestMain ( m * testing . M ) {
os . Exit ( func ( ) int {
var err error
tmpDir , err = ioutil . TempDir ( "" , "interposer_test" )
if err != nil {
panic ( err )
}
defer os . RemoveAll ( tmpDir )
origPATH = os . Getenv ( "PATH" )
err = os . Setenv ( "PATH" , "" )
if err != nil {
panic ( err )
}
return m . Run ( )
} ( ) )
}
func setup ( t * testing . T ) string {
f , err := ioutil . TempFile ( tmpDir , "interposer" )
if err != nil {
t . Fatal ( err )
}
defer f . Close ( )
err = ioutil . WriteFile ( f . Name ( ) + "_origpath" , [ ] byte ( origPATH ) , 0666 )
if err != nil {
t . Fatal ( err )
}
return f . Name ( )
}
func TestInterposer ( t * testing . T ) {
interposer := setup ( t )
logConfig := func ( name string ) paths . PathConfig {
if name == "true" {
return paths . PathConfig {
Log : false ,
Error : false ,
}
} else if name == "path_interposer_test_not_allowed" {
return paths . PathConfig {
Log : false ,
Error : true ,
}
}
return paths . PathConfig {
Log : true ,
Error : false ,
}
}
testCases := [ ] struct {
name string
args [ ] string
exitCode int
err error
logEntry string
} {
{
name : "direct call" ,
args : [ ] string { interposer } ,
exitCode : 1 ,
err : usage ,
} ,
{
name : "relative call" ,
args : [ ] string { filepath . Base ( interposer ) } ,
exitCode : 1 ,
err : usage ,
} ,
{
name : "true" ,
args : [ ] string { "/my/path/true" } ,
} ,
{
name : "relative true" ,
args : [ ] string { "true" } ,
} ,
{
name : "exit code" ,
args : [ ] string { "bash" , "-c" , "exit 42" } ,
exitCode : 42 ,
logEntry : "bash" ,
} ,
{
name : "signal" ,
args : [ ] string { "bash" , "-c" , "kill -9 $$" } ,
exitCode : 137 ,
logEntry : "bash" ,
} ,
{
name : "does not exist" ,
args : [ ] string { "path_interposer_test_does_not_exist" } ,
exitCode : 1 ,
err : fmt . Errorf ( ` exec: "path_interposer_test_does_not_exist": executable file not found in $PATH ` ) ,
logEntry : "path_interposer_test_does_not_exist" ,
} ,
{
name : "not allowed" ,
args : [ ] string { "path_interposer_test_not_allowed" } ,
exitCode : 1 ,
err : fmt . Errorf ( ` "path_interposer_test_not_allowed" is not allowed to be used. See https://android.googlesource.com/platform/build/+/master/Changes.md#PATH_Tools for more information. ` ) ,
logEntry : "path_interposer_test_not_allowed" ,
} ,
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
logged := false
logFunc := func ( logSocket string , entry * paths . LogEntry , done chan interface { } ) {
defer close ( done )
logged = true
if entry . Basename != testCase . logEntry {
t . Errorf ( "unexpected log entry:\nwant: %q\n got: %q" , testCase . logEntry , entry . Basename )
}
}
exitCode , err := Main ( ioutil . Discard , ioutil . Discard , interposer , testCase . args , mainOpts {
sendLog : logFunc ,
config : logConfig ,
} )
errstr := func ( err error ) string {
if err == nil {
return ""
}
return err . Error ( )
}
if errstr ( testCase . err ) != errstr ( err ) {
t . Errorf ( "unexpected error:\nwant: %v\n got: %v" , testCase . err , err )
}
if testCase . exitCode != exitCode {
t . Errorf ( "expected exit code %d, got %d" , testCase . exitCode , exitCode )
}
if ! logged && testCase . logEntry != "" {
t . Errorf ( "no log entry, but expected %q" , testCase . logEntry )
}
} )
}
}
func TestMissingPath ( t * testing . T ) {
interposer := setup ( t )
err := os . Remove ( interposer + "_origpath" )
if err != nil {
2018-07-14 06:25:15 +02:00
t . Fatal ( "Failed to remove:" , err )
2018-05-26 01:30:04 +02:00
}
exitCode , err := Main ( ioutil . Discard , ioutil . Discard , interposer , [ ] string { "true" } , mainOpts { } )
if err != usage {
t . Errorf ( "Unexpected error:\n got: %v\nwant: %v" , err , usage )
}
if exitCode != 1 {
t . Errorf ( "expected exit code %d, got %d" , 1 , exitCode )
}
}