From be427a3c3537415a7d85d92536daccb63d0de2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyori=20=ED=9A=A8=EB=A6=AC?= Date: Wed, 28 Feb 2024 00:34:57 +0800 Subject: [PATCH 1/6] not printf --- machine.go | 6 ++++++ machine_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/machine.go b/machine.go index 9db1fe1b..e5a702cc 100644 --- a/machine.go +++ b/machine.go @@ -214,7 +214,13 @@ func (m *Machine) AddLazyloadModules(mods ModuleLoaderMap) { m.lazyloadMods.Merge(mods) } +var ( + // NoopPrintFunc is a no-op print function for the Starlark runtime environment, it does nothing. + NoopPrintFunc PrintFunc = func(thread *starlark.Thread, msg string) {} +) + // SetPrintFunc sets the print function of the Starlark runtime environment. +// To disable printing, you can set it to NoopPrintFunc. Setting it to nil will invoke the default `fmt.Fprintln(os.Stderr, msg)` instead. func (m *Machine) SetPrintFunc(printFunc PrintFunc) { m.mu.Lock() defer m.mu.Unlock() diff --git a/machine_test.go b/machine_test.go index 716c1f94..739c9fd1 100644 --- a/machine_test.go +++ b/machine_test.go @@ -623,3 +623,34 @@ func TestMachine_GetStarlarkThread(t *testing.T) { t.Errorf("expected not nil, got nil") } } + +func Test_SetPrintFunc(t *testing.T) { + m := starlet.NewDefault() + // set print function + printFunc, cmpFunc := getPrintCompareFunc(t) + m.SetPrintFunc(printFunc) + // set code + code := `print("Aloha, Honua!")` + m.SetScript("aloha.star", []byte(code), nil) + // run + _, err := m.Run() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + // compare + cmpFunc("Aloha, Honua!\n") + + // set print function to nil + m.SetPrintFunc(nil) + m.SetScript("aloha.star", []byte(`print("Aloha, Honua! Nil")`), nil) + if _, err = m.Run(); err != nil { + t.Errorf("unexpected error: %v", err) + } + + // set print function to noop + m.SetPrintFunc(starlet.NoopPrintFunc) + m.SetScript("aloha.star", []byte(`print("Aloha, Honua! Noop")`), nil) + if _, err = m.Run(); err != nil { + t.Errorf("unexpected error: %v", err) + } +} From 9779f61bbb2b6fd1ef5a9d26c6a95cb732acee33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyori=20=ED=9A=A8=EB=A6=AC?= Date: Wed, 28 Feb 2024 00:52:04 +0800 Subject: [PATCH 2/6] printf --- machine_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/machine_test.go b/machine_test.go index 739c9fd1..445de01a 100644 --- a/machine_test.go +++ b/machine_test.go @@ -586,6 +586,21 @@ func TestMachine_SetScriptCache(t *testing.T) { t.Errorf("expected same error, got different --- err1: %v, err2: %v, err3: %v", err1, err2, err3) } } + + // ignore cache + { + m := starlet.NewDefault() + m.SetScriptCacheEnabled(true) + res, err := m.RunScript([]byte(script1), nil) + checkRes(501, err, res, 10) + + res, err = m.RunScript([]byte(script2), nil) + checkRes(502, err, res, 20) + + m.SetScriptCacheEnabled(false) + res, err = m.RunScript([]byte(script2), nil) + checkRes(503, err, res, 20) + } } func TestMachine_GetStarlarkPredeclared(t *testing.T) { From 9b052f084fec66736b89ff784c612a8938f6a8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyori=20=ED=9A=A8=EB=A6=AC?= Date: Wed, 28 Feb 2024 01:09:47 +0800 Subject: [PATCH 3/6] not allow cache --- exec.go | 6 +++--- run.go | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/exec.go b/exec.go index bf16f53e..29d65d9c 100644 --- a/exec.go +++ b/exec.go @@ -11,15 +11,15 @@ import ( // execStarlarkFile executes a Starlark file with the given filename and source, and returns the global environment and any error encountered. // If the cache is enabled, it will try to load the compiled program from the cache first, and save the compiled program to the cache after compilation. -func (m *Machine) execStarlarkFile(filename string, src interface{}) (starlark.StringDict, error) { +func (m *Machine) execStarlarkFile(filename string, src interface{}, allowCache bool) (starlark.StringDict, error) { // restore the arguments for starlark.ExecFileOptions opts := m.getFileOptions() thread := m.thread predeclared := m.predeclared hasCache := m.progCache != nil - // if cache is not enabled, just execute the original source - if !hasCache { + // if cache is not enabled or not allowed, just execute the original source + if !hasCache || !allowCache { return starlark.ExecFileOptions(opts, thread, filename, src, predeclared) } diff --git a/run.go b/run.go index bcfc4cce..3265cf8e 100644 --- a/run.go +++ b/run.go @@ -59,7 +59,7 @@ func (m *Machine) Run() (StringAnyMap, error) { m.mu.Lock() defer m.mu.Unlock() - return m.runInternal(context.Background(), nil) + return m.runInternal(context.Background(), nil, true) } // RunScript executes a script with additional variables, which take precedence over global variables and modules, returns the result. @@ -70,7 +70,7 @@ func (m *Machine) RunScript(content []byte, extras StringAnyMap) (StringAnyMap, m.scriptName = "direct.star" m.scriptContent = content m.scriptFS = nil - return m.runInternal(context.Background(), extras) + return m.runInternal(context.Background(), extras, false) } // RunFile executes a script from a file with additional variables, which take precedence over global variables and modules, returns the result. @@ -81,7 +81,7 @@ func (m *Machine) RunFile(name string, fileSys fs.FS, extras StringAnyMap) (Stri m.scriptName = name m.scriptContent = nil m.scriptFS = fileSys - return m.runInternal(context.Background(), extras) + return m.runInternal(context.Background(), extras, true) } // RunWithTimeout executes a preset script with a timeout and additional variables, which take precedence over global variables and modules, returns the result. @@ -91,7 +91,7 @@ func (m *Machine) RunWithTimeout(timeout time.Duration, extras StringAnyMap) (St ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - return m.runInternal(ctx, extras) + return m.runInternal(ctx, extras, true) } // RunWithContext executes a preset script within a specified context and additional variables, which take precedence over global variables and modules, returns the result. @@ -99,10 +99,10 @@ func (m *Machine) RunWithContext(ctx context.Context, extras StringAnyMap) (Stri m.mu.Lock() defer m.mu.Unlock() - return m.runInternal(ctx, extras) + return m.runInternal(ctx, extras, true) } -func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap) (out StringAnyMap, err error) { +func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap, allowCache bool) (out StringAnyMap, err error) { defer func() { if r := recover(); r != nil { err = errorStarlarkPanic("exec", r) @@ -168,7 +168,7 @@ func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap) (out Str // run with everything prepared m.runTimes++ - res, err := m.execStarlarkFile(scriptName, source) + res, err := m.execStarlarkFile(scriptName, source, allowCache) done <- struct{}{} // merge result as predeclared for next run From 4ccdb8e464f67664bb61b694ec22b422978266de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyori=20=ED=9A=A8=EB=A6=AC?= Date: Wed, 28 Feb 2024 06:14:05 +0800 Subject: [PATCH 4/6] refine --- run.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/run.go b/run.go index 3265cf8e..2ff03421 100644 --- a/run.go +++ b/run.go @@ -116,8 +116,9 @@ func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap, allowCac ) if m.scriptContent != nil { if scriptName == "" { - // for default name + // for default name, and disable cache to avoid conflict scriptName = "eval.star" + allowCache = false } source = m.scriptContent } else if m.scriptFS != nil { From afbac0b8ea6e5c055dfaee3bfb530fe0b094c508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyori=20=ED=9A=A8=EB=A6=AC?= Date: Wed, 28 Feb 2024 15:03:59 +0800 Subject: [PATCH 5/6] for cases --- machine_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/machine_test.go b/machine_test.go index 445de01a..410f68a7 100644 --- a/machine_test.go +++ b/machine_test.go @@ -601,6 +601,24 @@ func TestMachine_SetScriptCache(t *testing.T) { res, err = m.RunScript([]byte(script2), nil) checkRes(503, err, res, 20) } + + // skip cache + { + m := starlet.NewDefault() + m.SetScriptCacheEnabled(true) + m.SetScript("", []byte(script1), nil) + res, err := m.Run() + checkRes(601, err, res, 10) + + m.SetScript("", []byte(script2), nil) + res, err = m.Run() + checkRes(602, err, res, 20) + + m.SetScriptCacheEnabled(false) + m.SetScript("", []byte(script2), nil) + res, err = m.Run() + checkRes(603, err, res, 20) + } } func TestMachine_GetStarlarkPredeclared(t *testing.T) { From 5f46ca6ce5f4b376bbc4fad7d82d839f18162ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hyori=20=ED=9A=A8=EB=A6=AC?= Date: Wed, 28 Feb 2024 15:05:54 +0800 Subject: [PATCH 6/6] better comments --- machine_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/machine_test.go b/machine_test.go index 410f68a7..713b1810 100644 --- a/machine_test.go +++ b/machine_test.go @@ -587,7 +587,7 @@ func TestMachine_SetScriptCache(t *testing.T) { } } - // ignore cache + // ignore cache 1: run script will use default name "direct.star", disable cache to avoid conflict { m := starlet.NewDefault() m.SetScriptCacheEnabled(true) @@ -602,7 +602,7 @@ func TestMachine_SetScriptCache(t *testing.T) { checkRes(503, err, res, 20) } - // skip cache + // ignore cache 2: empty script name will set as "eval.star", disable cache to avoid conflict { m := starlet.NewDefault() m.SetScriptCacheEnabled(true)