blob: 38b292376a03d17408c089c07524cc7bcafe71f6 [file] [log] [blame]
Sasha Smundak24159db2020-10-26 15:43:21 -07001// Copyright 2021 Google LLC
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
15package rbcrun
16
17import (
18 "fmt"
19 "os"
20 "path/filepath"
21 "runtime"
Cole Faust5b8dda02023-11-07 11:14:58 -080022 "strings"
Sasha Smundak24159db2020-10-26 15:43:21 -070023 "testing"
24
25 "go.starlark.net/resolve"
26 "go.starlark.net/starlark"
27 "go.starlark.net/starlarktest"
28)
29
30// In order to use "assert.star" from go/starlark.net/starlarktest in the tests,
31// provide:
32// * load function that handles "assert.star"
33// * starlarktest.DataFile function that finds its location
34
35func init() {
36 starlarktestSetup()
37}
38
39func starlarktestSetup() {
40 resolve.AllowLambda = true
41 starlarktest.DataFile = func(pkgdir, filename string) string {
42 // The caller expects this function to return the path to the
43 // data file. The implementation assumes that the source file
44 // containing the caller and the data file are in the same
45 // directory. It's ugly. Not sure what's the better way.
46 // TODO(asmundak): handle Bazel case
47 _, starlarktestSrcFile, _, _ := runtime.Caller(1)
48 if filepath.Base(starlarktestSrcFile) != "starlarktest.go" {
49 panic(fmt.Errorf("this function should be called from starlarktest.go, got %s",
50 starlarktestSrcFile))
51 }
52 return filepath.Join(filepath.Dir(starlarktestSrcFile), filename)
53 }
54}
55
56// Common setup for the tests: create thread, change to the test directory
Cole Fausta874f882023-05-05 11:46:51 -070057func testSetup(t *testing.T) *starlark.Thread {
Sasha Smundak24159db2020-10-26 15:43:21 -070058 thread := &starlark.Thread{
59 Load: func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
60 if module == "assert.star" {
61 return starlarktest.LoadAssertModule()
62 }
63 return nil, fmt.Errorf("load not implemented")
64 }}
65 starlarktest.SetReporter(thread, t)
66 if err := os.Chdir(dataDir()); err != nil {
67 t.Fatal(err)
68 }
69 return thread
70}
71
72func dataDir() string {
73 _, thisSrcFile, _, _ := runtime.Caller(0)
74 return filepath.Join(filepath.Dir(thisSrcFile), "testdata")
Sasha Smundak24159db2020-10-26 15:43:21 -070075}
76
77func exerciseStarlarkTestFile(t *testing.T, starFile string) {
78 // In order to use "assert.star" from go/starlark.net/starlarktest in the tests, provide:
79 // * load function that handles "assert.star"
80 // * starlarktest.DataFile function that finds its location
Cole Fausta874f882023-05-05 11:46:51 -070081 if err := os.Chdir(dataDir()); err != nil {
82 t.Fatal(err)
83 }
Sasha Smundak24159db2020-10-26 15:43:21 -070084 thread := &starlark.Thread{
85 Load: func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
86 if module == "assert.star" {
87 return starlarktest.LoadAssertModule()
88 }
89 return nil, fmt.Errorf("load not implemented")
90 }}
91 starlarktest.SetReporter(thread, t)
92 _, thisSrcFile, _, _ := runtime.Caller(0)
93 filename := filepath.Join(filepath.Dir(thisSrcFile), starFile)
Cole Faustc63ce1a2023-05-09 14:56:36 -070094 thread.SetLocal(executionModeKey, ExecutionModeRbc)
95 thread.SetLocal(shellKey, "/bin/sh")
96 if _, err := starlark.ExecFile(thread, filename, nil, rbcBuiltins); err != nil {
Sasha Smundak24159db2020-10-26 15:43:21 -070097 if err, ok := err.(*starlark.EvalError); ok {
98 t.Fatal(err.Backtrace())
99 }
100 t.Fatal(err)
101 }
102}
103
Sasha Smundak24159db2020-10-26 15:43:21 -0700104func TestFileOps(t *testing.T) {
105 // TODO(asmundak): convert this to use exerciseStarlarkTestFile
Cole Fausta874f882023-05-05 11:46:51 -0700106 thread := testSetup(t)
Cole Faustc63ce1a2023-05-09 14:56:36 -0700107 if _, err := starlark.ExecFile(thread, "file_ops.star", nil, rbcBuiltins); err != nil {
Sasha Smundak24159db2020-10-26 15:43:21 -0700108 if err, ok := err.(*starlark.EvalError); ok {
109 t.Fatal(err.Backtrace())
110 }
111 t.Fatal(err)
112 }
113}
114
115func TestLoad(t *testing.T) {
116 // TODO(asmundak): convert this to use exerciseStarlarkTestFile
Cole Fausta874f882023-05-05 11:46:51 -0700117 thread := testSetup(t)
Sasha Smundak24159db2020-10-26 15:43:21 -0700118 thread.Load = func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
119 if module == "assert.star" {
120 return starlarktest.LoadAssertModule()
121 } else {
122 return loader(thread, module)
123 }
124 }
125 dir := dataDir()
Cole Faustc63ce1a2023-05-09 14:56:36 -0700126 if err := os.Chdir(filepath.Dir(dir)); err != nil {
127 t.Fatal(err)
128 }
Cole Faust386b3742023-06-06 16:55:58 -0700129 thread.SetLocal(allowExternalEntrypointKey, false)
Cole Faust5b8dda02023-11-07 11:14:58 -0800130 thread.SetLocal(callingFileKey, "testdata/load.star")
Cole Faustc63ce1a2023-05-09 14:56:36 -0700131 thread.SetLocal(executionModeKey, ExecutionModeRbc)
132 if _, err := starlark.ExecFile(thread, "testdata/load.star", nil, rbcBuiltins); err != nil {
Sasha Smundak24159db2020-10-26 15:43:21 -0700133 if err, ok := err.(*starlark.EvalError); ok {
134 t.Fatal(err.Backtrace())
135 }
136 t.Fatal(err)
137 }
138}
139
Cole Faust5b8dda02023-11-07 11:14:58 -0800140func TestBzlLoadsScl(t *testing.T) {
141 moduleCache = make(map[string]*modentry)
142 dir := dataDir()
143 if err := os.Chdir(filepath.Dir(dir)); err != nil {
144 t.Fatal(err)
145 }
Cole Faust63092342023-11-13 11:21:08 -0800146 vars, _, err := Run("testdata/bzl_loads_scl.bzl", nil, ExecutionModeRbc, false)
Cole Faust5b8dda02023-11-07 11:14:58 -0800147 if err != nil {
148 t.Fatal(err)
149 }
150 if val, ok := vars["foo"]; !ok {
151 t.Fatalf("Failed to load foo variable")
152 } else if val.(starlark.String) != "bar" {
153 t.Fatalf("Expected \"bar\", got %q", val)
154 }
155}
156
157func TestNonEntrypointBzlLoadsScl(t *testing.T) {
158 moduleCache = make(map[string]*modentry)
159 dir := dataDir()
160 if err := os.Chdir(filepath.Dir(dir)); err != nil {
161 t.Fatal(err)
162 }
Cole Faust63092342023-11-13 11:21:08 -0800163 vars, _, err := Run("testdata/bzl_loads_scl_2.bzl", nil, ExecutionModeRbc, false)
Cole Faust5b8dda02023-11-07 11:14:58 -0800164 if err != nil {
165 t.Fatal(err)
166 }
167 if val, ok := vars["foo"]; !ok {
168 t.Fatalf("Failed to load foo variable")
169 } else if val.(starlark.String) != "bar" {
170 t.Fatalf("Expected \"bar\", got %q", val)
171 }
172}
173
174func TestSclLoadsBzl(t *testing.T) {
175 moduleCache = make(map[string]*modentry)
176 dir := dataDir()
177 if err := os.Chdir(filepath.Dir(dir)); err != nil {
178 t.Fatal(err)
179 }
180 _, _, err := Run("testdata/scl_incorrectly_loads_bzl.scl", nil, ExecutionModeScl, false)
181 if err == nil {
182 t.Fatal("Expected failure")
183 }
184 if !strings.Contains(err.Error(), ".scl files can only load other .scl files") {
185 t.Fatalf("Expected error to contain \".scl files can only load other .scl files\": %q", err.Error())
186 }
187}
188
Cole Faustccd26802023-11-09 14:28:34 -0800189func TestCantLoadSymlink(t *testing.T) {
190 moduleCache = make(map[string]*modentry)
191 dir := dataDir()
192 if err := os.Chdir(filepath.Dir(dir)); err != nil {
193 t.Fatal(err)
194 }
195 _, _, err := Run("testdata/test_scl_symlink.scl", nil, ExecutionModeScl, false)
196 if err == nil {
197 t.Fatal("Expected failure")
198 }
199 if !strings.Contains(err.Error(), "symlinks to starlark files are not allowed") {
200 t.Fatalf("Expected error to contain \"symlinks to starlark files are not allowed\": %q", err.Error())
201 }
202}
203
Sasha Smundak24159db2020-10-26 15:43:21 -0700204func TestShell(t *testing.T) {
Sasha Smundak24159db2020-10-26 15:43:21 -0700205 exerciseStarlarkTestFile(t, "testdata/shell.star")
206}