diff --git a/api/golang/core/lib/shared_utils/parsed_git_url.go b/api/golang/core/lib/shared_utils/parsed_git_url.go index 5a413712b8..b2944f20fe 100644 --- a/api/golang/core/lib/shared_utils/parsed_git_url.go +++ b/api/golang/core/lib/shared_utils/parsed_git_url.go @@ -104,7 +104,7 @@ func ParseGitURL(packageURL string) (*ParsedGitURL, error) { if err != nil { return nil, stacktrace.Propagate(err, "Error parsing the URL with scheme for module '%v'", packageURLPrefixedWithHttps) } - if parsedURL.Host != GithubDomainPrefix { + if strings.ToLower(parsedURL.Host) != GithubDomainPrefix { return nil, stacktrace.NewError("Error parsing the URL of module. We only support modules on Github for now but got '%v'", packageURL) } diff --git a/core/server/api_container/server/startosis_engine/builtins/import_module/import_module.go b/core/server/api_container/server/startosis_engine/builtins/import_module/import_module.go index 40daa464b8..36d36afa20 100644 --- a/core/server/api_container/server/startosis_engine/builtins/import_module/import_module.go +++ b/core/server/api_container/server/startosis_engine/builtins/import_module/import_module.go @@ -55,6 +55,7 @@ func NewImportModule( }, Capabilities: &importModuleCapabilities{ + packageId: packageId, packageContentProvider: packageContentProvider, recursiveInterpret: recursiveInterpret, moduleGlobalCache: moduleGlobalCache, @@ -64,6 +65,7 @@ func NewImportModule( } type importModuleCapabilities struct { + packageId string packageContentProvider startosis_packages.PackageContentProvider recursiveInterpret func(moduleId string, scriptContent string) (starlark.StringDict, *startosis_errors.InterpretationError) moduleGlobalCache map[string]*startosis_packages.ModuleCacheEntry @@ -76,7 +78,7 @@ func (builtin *importModuleCapabilities) Interpret(locatorOfModuleInWhichThisBui return nil, explicitInterpretationError(err) } relativeOrAbsoluteModuleLocator := moduleLocatorArgValue.GoString() - absoluteModuleLocator, relativePathParsingInterpretationErr := builtin.packageContentProvider.GetAbsoluteLocatorForRelativeLocator(locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteModuleLocator, builtin.packageReplaceOptions) + absoluteModuleLocator, relativePathParsingInterpretationErr := builtin.packageContentProvider.GetAbsoluteLocator(builtin.packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteModuleLocator, builtin.packageReplaceOptions) if relativePathParsingInterpretationErr != nil { return nil, relativePathParsingInterpretationErr } diff --git a/core/server/api_container/server/startosis_engine/builtins/read_file/read_file.go b/core/server/api_container/server/startosis_engine/builtins/read_file/read_file.go index 6ab3d5197a..f08d70e3ea 100644 --- a/core/server/api_container/server/startosis_engine/builtins/read_file/read_file.go +++ b/core/server/api_container/server/startosis_engine/builtins/read_file/read_file.go @@ -36,6 +36,7 @@ func NewReadFileHelper( }, Capabilities: &readFileCapabilities{ + packageId: packageId, packageContentProvider: packageContentProvider, packageReplaceOptions: packageReplaceOptions, }, @@ -43,6 +44,7 @@ func NewReadFileHelper( } type readFileCapabilities struct { + packageId string packageContentProvider startosis_packages.PackageContentProvider packageReplaceOptions map[string]string } @@ -53,7 +55,7 @@ func (builtin *readFileCapabilities) Interpret(locatorOfModuleInWhichThisBuiltIn return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for arg '%s'", srcValue) } fileToReadStr := srcValue.GoString() - fileToReadStr, relativePathParsingInterpretationErr := builtin.packageContentProvider.GetAbsoluteLocatorForRelativeLocator(locatorOfModuleInWhichThisBuiltInIsBeingCalled, fileToReadStr, builtin.packageReplaceOptions) + fileToReadStr, relativePathParsingInterpretationErr := builtin.packageContentProvider.GetAbsoluteLocator(builtin.packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, fileToReadStr, builtin.packageReplaceOptions) if relativePathParsingInterpretationErr != nil { return nil, relativePathParsingInterpretationErr } diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/upload_files/upload_files.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/upload_files/upload_files.go index cee28132b0..f2e0cce86d 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/upload_files/upload_files.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/upload_files/upload_files.go @@ -68,6 +68,7 @@ func NewUploadFiles( archivePathOnDisk: "", // populated at interpretation time filesArtifactMd5: nil, // populated at interpretation time packageReplaceOptions: packageReplaceOptions, + packageId: packageId, } }, @@ -87,6 +88,7 @@ type UploadFilesCapabilities struct { archivePathOnDisk string filesArtifactMd5 []byte packageReplaceOptions map[string]string + packageId string } func (builtin *UploadFilesCapabilities) Interpret(locatorOfModuleInWhichThisBuiltInIsBeingCalled string, arguments *builtin_argument.ArgumentValuesSet) (starlark.Value, *startosis_errors.InterpretationError) { @@ -109,7 +111,7 @@ func (builtin *UploadFilesCapabilities) Interpret(locatorOfModuleInWhichThisBuil return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", SrcArgName) } - absoluteLocator, interpretationErr := builtin.packageContentProvider.GetAbsoluteLocatorForRelativeLocator(locatorOfModuleInWhichThisBuiltInIsBeingCalled, src.GoString(), builtin.packageReplaceOptions) + absoluteLocator, interpretationErr := builtin.packageContentProvider.GetAbsoluteLocator(builtin.packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, src.GoString(), builtin.packageReplaceOptions) if interpretationErr != nil { return nil, startosis_errors.WrapWithInterpretationError(interpretationErr, "Tried to convert locator '%v' into absolute locator but failed", src.GoString()) } diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_framework_test.go index 337c853456..083cf524e1 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_framework_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_framework_test.go @@ -39,7 +39,7 @@ func (suite *KurtosisHelperTestSuite) TestImportFile() { moduleGlobalCache := map[string]*startosis_packages.ModuleCacheEntry{} suite.packageContentProvider.EXPECT().GetModuleContents(testModuleFileName).Return("Hello World!", nil) - suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(startosis_constants.PackageIdPlaceholderForStandaloneScript, testModuleRelativeLocator, testNoPackageReplaceOptions).Return(testModuleFileName, nil) + suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(testModulePackageId, startosis_constants.PackageIdPlaceholderForStandaloneScript, testModuleRelativeLocator, testNoPackageReplaceOptions).Return(testModuleFileName, nil) suite.run(&importModuleTestCase{ T: suite.T(), diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_with_local_absolute_locator_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_with_local_absolute_locator_framework_test.go index e4980692a2..8646076743 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_with_local_absolute_locator_framework_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/import_module_with_local_absolute_locator_framework_test.go @@ -33,13 +33,13 @@ type importModuleWithLocalAbsoluteLocatorTestCase struct { } func (suite *KurtosisHelperTestSuite) TestImportFileWithLocalAbsoluteLocatorShouldNotBeValid() { - suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(testModulePackageId, testModuleFileName, testNoPackageReplaceOptions).Return("", startosis_errors.NewInterpretationError(importModuleWithLocalAbsoluteLocatorExpectedErrorMsg)) + suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(testModulePackageId, testModuleMainFileLocator, testModuleFileName, testNoPackageReplaceOptions).Return("", startosis_errors.NewInterpretationError(importModuleWithLocalAbsoluteLocatorExpectedErrorMsg)) // start with an empty cache to validate it gets populated moduleGlobalCache := map[string]*startosis_packages.ModuleCacheEntry{} suite.runShouldFail( - testModulePackageId, + testModuleMainFileLocator, &importModuleWithLocalAbsoluteLocatorTestCase{ T: suite.T(), moduleGlobalCache: moduleGlobalCache, diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_framework_test.go index 27fd68c5f9..e81cf4efc9 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_framework_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_framework_test.go @@ -18,7 +18,7 @@ type readFileTestCase struct { } func (suite *KurtosisHelperTestSuite) TestReadFile() { - suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(startosis_constants.PackageIdPlaceholderForStandaloneScript, testModuleRelativeLocator, testNoPackageReplaceOptions).Return(testModuleFileName, nil) + suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(testModulePackageId, startosis_constants.PackageIdPlaceholderForStandaloneScript, testModuleRelativeLocator, testNoPackageReplaceOptions).Return(testModuleFileName, nil) suite.packageContentProvider.EXPECT().GetModuleContents(testModuleFileName).Return("Hello World!", nil) suite.run(&readFileTestCase{ @@ -40,7 +40,7 @@ func (t *readFileTestCase) GetStarlarkCodeForAssertion() string { } func (t *readFileTestCase) Assert(result starlark.Value) { - t.packageContentProvider.AssertCalled(t, "GetAbsoluteLocatorForRelativeLocator", startosis_constants.PackageIdPlaceholderForStandaloneScript, testModuleRelativeLocator, testNoPackageReplaceOptions) + t.packageContentProvider.AssertCalled(t, "GetAbsoluteLocator", testModulePackageId, startosis_constants.PackageIdPlaceholderForStandaloneScript, testModuleRelativeLocator, testNoPackageReplaceOptions) t.packageContentProvider.AssertCalled(t, "GetModuleContents", testModuleFileName) require.Equal(t, result, starlark.String("Hello World!")) } diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_with_local_absolute_locator_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_with_local_absolute_locator_framework_test.go index 661a98e71c..77eb2cdab3 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_with_local_absolute_locator_framework_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/read_file_with_local_absolute_locator_framework_test.go @@ -21,10 +21,10 @@ type readFileWithLocalAbsoluteLocatorTestCase struct { } func (suite *KurtosisHelperTestSuite) TestReadFileWithLocalAbsoluteLocatorShouldNotBeValid() { - suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(testModulePackageId, testModuleFileName, testNoPackageReplaceOptions).Return("", startosis_errors.NewInterpretationError(readFileWithLocalAbsoluteLocatorExpectedErrorMsg)) + suite.packageContentProvider.EXPECT().GetAbsoluteLocatorForRelativeLocator(testModulePackageId, testModuleMainFileLocator, testModuleFileName, testNoPackageReplaceOptions).Return("", startosis_errors.NewInterpretationError(readFileWithLocalAbsoluteLocatorExpectedErrorMsg)) suite.runShouldFail( - testModulePackageId, + testModuleMainFileLocator, &readFileWithLocalAbsoluteLocatorTestCase{ T: suite.T(), packageContentProvider: suite.packageContentProvider, diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go index bca3eb8c22..df2aedfa9e 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go @@ -22,6 +22,7 @@ var ( testSrcPath = "/path/to/file.txt" testModulePackageId = "github.com/kurtosistech/test-package" + testModuleMainFileLocator = "github.com/kurtosistech/test-package/main.star" testModuleFileName = "github.com/kurtosistech/test-package/helpers.star" testModuleRelativeLocator = "./helpers.star" diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/suite_kurtosis_helper_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/suite_kurtosis_helper_test.go index 423fbaeb8c..d2b11257ef 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/suite_kurtosis_helper_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/suite_kurtosis_helper_test.go @@ -45,13 +45,13 @@ func (suite *KurtosisHelperTestSuite) run(builtin KurtosisHelperBaseTest) { builtin.Assert(result) } -func (suite *KurtosisHelperTestSuite) runShouldFail(packageId string, builtin KurtosisHelperBaseTest, expectedErrMsg string) { +func (suite *KurtosisHelperTestSuite) runShouldFail(moduleName string, builtin KurtosisHelperBaseTest, expectedErrMsg string) { // Add the KurtosisPlanInstruction that is being tested helper := builtin.GetHelper() suite.starlarkEnv[helper.GetName()] = starlark.NewBuiltin(helper.GetName(), helper.CreateBuiltin()) starlarkCode := builtin.GetStarlarkCode() - _, err := starlark.ExecFile(suite.starlarkThread, packageId, codeToExecute(starlarkCode), suite.starlarkEnv) + _, err := starlark.ExecFile(suite.starlarkThread, moduleName, codeToExecute(starlarkCode), suite.starlarkEnv) suite.Require().Error(err, "Expected to fail running starlark code %s, but it didn't fail", builtin.GetStarlarkCode()) suite.Require().Equal(expectedErrMsg, err.Error()) } diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go index 95c6efcf9a..53aa509ab8 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go @@ -44,6 +44,7 @@ const ( ) type GitPackageContentProvider struct { + // Where to temporarily store packages while packagesTmpDir string packagesDir string packageReplaceOptionsRepository *packageReplaceOptionsRepository @@ -205,28 +206,31 @@ func (provider *GitPackageContentProvider) StorePackageContents(packageId string return packageAbsolutePathOnDisk, nil } -func (provider *GitPackageContentProvider) GetAbsoluteLocatorForRelativeLocator( - parentModuleId string, - maybeRelativeLocator string, +func (provider *GitPackageContentProvider) GetAbsoluteLocator( + packageId string, + sourceModuleLocator string, + relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string, ) (string, *startosis_errors.InterpretationError) { var absoluteLocator string - if isSamePackageLocalAbsoluteLocator(maybeRelativeLocator, parentModuleId) { - return "", startosis_errors.NewInterpretationError("The locator '%s' set in attribute is not a 'local relative locator'. Local absolute locators are not allowed you should modified it to be a valid 'local relative locator'", maybeRelativeLocator) + if shouldBlockAbsoluteLocatorBecauseIsInTheSameSourceModuleLocatorPackage(relativeOrAbsoluteLocator, sourceModuleLocator, packageId) { + return "", startosis_errors.NewInterpretationError("Locator '%s' is referencing a file within the same package using absolute import syntax, but only relative import syntax (path starting with '/' or '.') is allowed for within-package imports", relativeOrAbsoluteLocator) } // maybe it's not a relative url in which case we return the url - _, errorParsingUrl := shared_utils.ParseGitURL(maybeRelativeLocator) + _, errorParsingUrl := shared_utils.ParseGitURL(relativeOrAbsoluteLocator) if errorParsingUrl == nil { - absoluteLocator = maybeRelativeLocator + // Parsing succeeded, meaning this is already an absolute locator and no relative -> absolute translation is needed + absoluteLocator = relativeOrAbsoluteLocator } else { - parsedParentModuleId, errorParsingPackageId := shared_utils.ParseGitURL(parentModuleId) + // Parsing did not succeed, meaning this is a relative locator + sourceModuleParsedGitUrl, errorParsingPackageId := shared_utils.ParseGitURL(sourceModuleLocator) if errorParsingPackageId != nil { - return "", startosis_errors.NewInterpretationError("Parent package id '%v' isn't a valid locator; relative URLs don't work with standalone scripts", parentModuleId) + return "", startosis_errors.NewInterpretationError("Source module locator '%v' isn't a valid locator; relative URLs don't work with standalone scripts", sourceModuleLocator) } - absoluteLocator = parsedParentModuleId.GetAbsoluteLocatorRelativeToThisURL(maybeRelativeLocator) + absoluteLocator = sourceModuleParsedGitUrl.GetAbsoluteLocatorRelativeToThisURL(relativeOrAbsoluteLocator) } replacedAbsoluteLocator := replaceAbsoluteLocator(absoluteLocator, packageReplaceOptions) diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go index d605565c88..cb65cbe0d5 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go @@ -16,9 +16,10 @@ import ( ) const ( - packagesDirRelPath = "startosis-packages" - packagesTmpDirRelPath = "tmp-startosis-packages" - packageDescriptionForTest = "package description test" + packagesDirRelPath = "startosis-packages" + packagesTmpDirRelPath = "tmp-startosis-packages" + packageDescriptionForTest = "package description test" + localAbsoluteLocatorNotAllowedMsg = "is referencing a file within the same package using absolute import syntax" ) var noPackageReplaceOptions = map[string]string{} @@ -199,35 +200,37 @@ func TestGetAbsolutePathOnDisk_WorksForNonInMainBranchLocators(t *testing.T) { require.Equal(t, path.Join(packageDir, "kurtosis-tech", "sample-dependency-package", "main.star"), pathOnDisk) } -func TestGetAbsoluteLocatorForRelativeModuleLocator_SucceedsForRelativeFile(t *testing.T) { +func TestGetAbsoluteLocator_SucceedsForRelativeFile(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) + packageId := "github.com/kurtosis-tech/avalanche-package" parentModuleId := "github.com/kurtosis-tech/avalanche-package/src/builder.star" maybeRelativeLocator := "../static_files/config.json.tmpl" - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, noPackageReplaceOptions) + absoluteLocator, err := provider.GetAbsoluteLocator(packageId, parentModuleId, maybeRelativeLocator, noPackageReplaceOptions) + require.Nil(t, err) expectedAbsoluteLocator := "github.com/kurtosis-tech/avalanche-package/static_files/config.json.tmpl" - require.Nil(t, err) require.Equal(t, expectedAbsoluteLocator, absoluteLocator) parentModuleId2 := "github.com/kurtosis-tech/avalanche-package/src/builder.star" maybeRelativeLocator2 := "/static_files/genesis.json" - absoluteLocator2, err2 := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId2, maybeRelativeLocator2, noPackageReplaceOptions) + absoluteLocator2, err2 := provider.GetAbsoluteLocator(packageId, parentModuleId2, maybeRelativeLocator2, noPackageReplaceOptions) expectedAbsoluteLocator2 := "github.com/kurtosis-tech/avalanche-package/static_files/genesis.json" require.Nil(t, err2) require.Equal(t, expectedAbsoluteLocator2, absoluteLocator2) } -func TestGetAbsoluteLocatorForRelativeModuleLocator_RegularReplaceSucceeds(t *testing.T) { +func TestGetAbsoluteLocator_RegularReplaceSucceeds(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) + packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" maybeRelativeLocator := "github.com/kurtosis-tech/sample-dependency-package/main.star" packageReplaceOptions := map[string]string{ "github.com/kurtosis-tech/sample-dependency-package": "github.com/kurtosis-tech/another-sample-dependency-package", } - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, packageReplaceOptions) + absoluteLocator, err := provider.GetAbsoluteLocator(packageId, parentModuleId, maybeRelativeLocator, packageReplaceOptions) expectedAbsoluteLocator := "github.com/kurtosis-tech/another-sample-dependency-package/main.star" require.Nil(t, err) @@ -235,16 +238,17 @@ func TestGetAbsoluteLocatorForRelativeModuleLocator_RegularReplaceSucceeds(t *te } -func TestGetAbsoluteLocatorForRelativeModuleLocator_RootPackageReplaceSucceeds(t *testing.T) { +func TestGetAbsoluteLocator_RootPackageReplaceSucceeds(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) + packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" maybeRelativeLocator := "github.com/kurtosis-tech/another-sample-dependency-package/main.star" packageReplaceOptions := map[string]string{ "github.com/kurtosis-tech/another-sample-dependency-package": "github.com/kurtosis-tech/root-package-replaced", "github.com/kurtosis-tech/another-sample-dependency-package/subpackage": "github.com/kurtosis-tech/sub-package-replaced", } - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, packageReplaceOptions) + absoluteLocator, err := provider.GetAbsoluteLocator(packageId, parentModuleId, maybeRelativeLocator, packageReplaceOptions) expectedAbsoluteLocator := "github.com/kurtosis-tech/root-package-replaced/main.star" require.Nil(t, err) @@ -252,16 +256,17 @@ func TestGetAbsoluteLocatorForRelativeModuleLocator_RootPackageReplaceSucceeds(t } -func TestGetAbsoluteLocatorForRelativeModuleLocator_SubPackageReplaceSucceeds(t *testing.T) { +func TestGetAbsoluteLocator_SubPackageReplaceSucceeds(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) + packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" maybeRelativeLocator := "github.com/kurtosis-tech/another-sample-dependency-package/subpackage/main.star" packageReplaceOptions := map[string]string{ "github.com/kurtosis-tech/another-sample-dependency-package": "github.com/kurtosis-tech/root-package-replaced", "github.com/kurtosis-tech/another-sample-dependency-package/subpackage": "github.com/kurtosis-tech/sub-package-replaced", } - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, packageReplaceOptions) + absoluteLocator, err := provider.GetAbsoluteLocator(packageId, parentModuleId, maybeRelativeLocator, packageReplaceOptions) expectedAbsoluteLocator := "github.com/kurtosis-tech/sub-package-replaced/main.star" require.Nil(t, err) @@ -269,49 +274,101 @@ func TestGetAbsoluteLocatorForRelativeModuleLocator_SubPackageReplaceSucceeds(t } -func TestGetAbsoluteLocatorForRelativeModuleLocator_ReplacePackageInternalModuleSucceeds(t *testing.T) { +func TestGetAbsoluteLocator_ReplacePackageInternalModuleSucceeds(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) + packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" maybeRelativeLocator := "github.com/kurtosis-tech/another-sample-dependency-package/folder/module.star" packageReplaceOptions := map[string]string{ "github.com/kurtosis-tech/another-sample-dependency-package": "github.com/kurtosis-tech/root-package-replaced", } - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, packageReplaceOptions) + absoluteLocator, err := provider.GetAbsoluteLocator(packageId, parentModuleId, maybeRelativeLocator, packageReplaceOptions) expectedAbsoluteLocator := "github.com/kurtosis-tech/root-package-replaced/folder/module.star" require.Nil(t, err) require.Equal(t, expectedAbsoluteLocator, absoluteLocator) } -func TestGetAbsoluteLocatorForRelativeModuleLocator_NoMainBranchReplaceSucceeds(t *testing.T) { +func TestGetAbsoluteLocator_NoMainBranchReplaceSucceeds(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) + packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" maybeRelativeLocator := "github.com/kurtosis-tech/sample-dependency-package/main.star" packageReplaceOptions := map[string]string{ "github.com/kurtosis-tech/sample-dependency-package": "github.com/kurtosis-tech/sample-dependency-package@no-main-branch", } - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, packageReplaceOptions) + absoluteLocator, err := provider.GetAbsoluteLocator(packageId, parentModuleId, maybeRelativeLocator, packageReplaceOptions) expectedAbsoluteLocator := "github.com/kurtosis-tech/sample-dependency-package@no-main-branch/main.star" require.Nil(t, err) require.Equal(t, expectedAbsoluteLocator, absoluteLocator) } -func TestGetAbsoluteLocatorForRelativeModuleLocator_LocalPackagehReplaceSucceeds(t *testing.T) { +func TestGetAbsoluteLocator_ShouldBlockSamePackageAbsoluteLocator(t *testing.T) { provider := NewGitPackageContentProvider("", "", nil) - parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" - maybeRelativeLocator := "github.com/kurtosis-tech/sample-dependency-package/main.star" - packageReplaceOptions := map[string]string{ - "github.com/kurtosis-tech/sample-dependency-package": "../local-sample-dependency-package", - } - absoluteLocator, err := provider.GetAbsoluteLocatorForRelativeLocator(parentModuleId, maybeRelativeLocator, packageReplaceOptions) + packageId := "github.com/main-package" + locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-package/main.star" + maybeRelativeLocator := "github.com/main-package/file.star" + + _, err := provider.GetAbsoluteLocator(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, maybeRelativeLocator, noPackageReplaceOptions) + require.ErrorContains(t, err, localAbsoluteLocatorNotAllowedMsg) +} - expectedAbsoluteLocator := "github.com/kurtosis-tech/sample-dependency-package/main.star" +func TestGetAbsoluteLocator_ShouldBlockSamePackageAbsoluteLocatorInSubfolder(t *testing.T) { + provider := NewGitPackageContentProvider("", "", nil) + + packageId := "github.com/main-package" + locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-package/main.star" + maybeRelativeLocator := "github.com/main-package/sub-folder/file.star" + + _, err := provider.GetAbsoluteLocator(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, maybeRelativeLocator, noPackageReplaceOptions) + require.ErrorContains(t, err, localAbsoluteLocatorNotAllowedMsg) +} + +func TestGetAbsoluteLocator_SameRepositorySubpackagesShouldNotBeBlocked(t *testing.T) { + provider := NewGitPackageContentProvider("", "", nil) + + packageId := "github.com/main-project/package1-in-subfolder" + locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-project/package1-in-subfolder/main.star" + maybeRelativeLocator := "github.com/main-project/package2-in-subfolder/file.star" + + _, err := provider.GetAbsoluteLocator(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, maybeRelativeLocator, noPackageReplaceOptions) require.Nil(t, err) - require.Equal(t, expectedAbsoluteLocator, absoluteLocator) +} + +func TestGetAbsoluteLocator_RelativeLocatorShouldNotBeBlocked(t *testing.T) { + provider := NewGitPackageContentProvider("", "", nil) + + packageId := "github.com/main-package" + locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-package/main.star" + maybeRelativeLocator := "./sub-folder/file.star" + + _, err := provider.GetAbsoluteLocator(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, maybeRelativeLocator, noPackageReplaceOptions) + require.Nil(t, err) +} + +func TestGetAbsoluteLocator_AbsoluteLocatorIsInRootPackageButSourceIsNotShouldNotBeBlocked(t *testing.T) { + provider := NewGitPackageContentProvider("", "", nil) + + packageId := "github.com/main-package" + locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/child-package/main.star" + maybeRelativeLocator := "github.com/main-package/file.star" + + _, err := provider.GetAbsoluteLocator(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, maybeRelativeLocator, noPackageReplaceOptions) + require.Nil(t, err) +} + +func Test_isSamePackageLocalAbsoluteLocator_TestDetectionInSubpath(t *testing.T) { + result := shouldBlockAbsoluteLocatorBecauseIsInTheSameSourceModuleLocatorPackage("github.com/author/package/bang/lib.star", "github.com/author/package/main.star", "github.com/author/package/") + require.True(t, result) +} + +func Test_isSamePackageLocalAbsoluteLocator_TestDetectionInDifferentSubdirectories(t *testing.T) { + result := shouldBlockAbsoluteLocatorBecauseIsInTheSameSourceModuleLocatorPackage("github.com/author/package/subdir1/file1.star", "github.com/author/package/subdir2/file2.star", "github.com/author/package/") + require.True(t, result) } func Test_getPathToPackageRoot(t *testing.T) { diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/locators.go b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/locators.go index 491104d947..48e168bed5 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/locators.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/locators.go @@ -18,8 +18,12 @@ func isLocalLocator(locator string) bool { return false } -func isSamePackageLocalAbsoluteLocator(locator string, parentPackageId string) bool { - return strings.HasPrefix(locator, parentPackageId) +func shouldBlockAbsoluteLocatorBecauseIsInTheSameSourceModuleLocatorPackage(relativeOrAbsoluteLocator string, sourceModuleLocator string, rootPackageId string) bool { + + isSourceModuleInRootPackage := strings.HasPrefix(sourceModuleLocator, rootPackageId) + isAbsoluteLocatorInRootPackage := strings.HasPrefix(relativeOrAbsoluteLocator, rootPackageId) + + return isSourceModuleInRootPackage && isAbsoluteLocatorInRootPackage } func replaceAbsoluteLocator(absoluteLocator string, packageReplaceOptions map[string]string) string { diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider.go b/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider.go index 83e9472cf1..bcfafab431 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider.go @@ -77,23 +77,67 @@ func (_c *MockPackageContentProvider_ClonePackage_Call) RunAndReturn(run func(st return _c } -// GetAbsoluteLocatorForRelativeLocator provides a mock function with given fields: packageId, relativeOrAbsoluteLocator, packageReplaceOptions -func (_m *MockPackageContentProvider) GetAbsoluteLocatorForRelativeLocator(packageId string, relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) { - ret := _m.Called(packageId, relativeOrAbsoluteLocator, packageReplaceOptions) +// CloneReplacedPackagesIfNeeded provides a mock function with given fields: currentPackageReplaceOptions +func (_m *MockPackageContentProvider) CloneReplacedPackagesIfNeeded(currentPackageReplaceOptions map[string]string) *startosis_errors.InterpretationError { + ret := _m.Called(currentPackageReplaceOptions) + + var r0 *startosis_errors.InterpretationError + if rf, ok := ret.Get(0).(func(map[string]string) *startosis_errors.InterpretationError); ok { + r0 = rf(currentPackageReplaceOptions) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*startosis_errors.InterpretationError) + } + } + + return r0 +} + +// MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CloneReplacedPackagesIfNeeded' +type MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call struct { + *mock.Call +} + +// CloneReplacedPackagesIfNeeded is a helper method to define mock.On call +// - currentPackageReplaceOptions map[string]string +func (_e *MockPackageContentProvider_Expecter) CloneReplacedPackagesIfNeeded(currentPackageReplaceOptions interface{}) *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call { + return &MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call{Call: _e.mock.On("CloneReplacedPackagesIfNeeded", currentPackageReplaceOptions)} +} + +func (_c *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call) Run(run func(currentPackageReplaceOptions map[string]string)) *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(map[string]string)) + }) + return _c +} + +func (_c *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call) Return(_a0 *startosis_errors.InterpretationError) *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call) RunAndReturn(run func(map[string]string) *startosis_errors.InterpretationError) *MockPackageContentProvider_CloneReplacedPackagesIfNeeded_Call { + _c.Call.Return(run) + return _c +} + +// GetAbsoluteLocatorForRelativeLocator provides a mock function with given fields: packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteLocator, packageReplaceOptions +func (_m *MockPackageContentProvider) GetAbsoluteLocator(packageId string, locatorOfModuleInWhichThisBuiltInIsBeingCalled string, relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) { + ret := _m.Called(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteLocator, packageReplaceOptions) var r0 string var r1 *startosis_errors.InterpretationError - if rf, ok := ret.Get(0).(func(string, string, map[string]string) (string, *startosis_errors.InterpretationError)); ok { - return rf(packageId, relativeOrAbsoluteLocator, packageReplaceOptions) + if rf, ok := ret.Get(0).(func(string, string, string, map[string]string) (string, *startosis_errors.InterpretationError)); ok { + return rf(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteLocator, packageReplaceOptions) } - if rf, ok := ret.Get(0).(func(string, string, map[string]string) string); ok { - r0 = rf(packageId, relativeOrAbsoluteLocator, packageReplaceOptions) + if rf, ok := ret.Get(0).(func(string, string, string, map[string]string) string); ok { + r0 = rf(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteLocator, packageReplaceOptions) } else { r0 = ret.Get(0).(string) } - if rf, ok := ret.Get(1).(func(string, string, map[string]string) *startosis_errors.InterpretationError); ok { - r1 = rf(packageId, relativeOrAbsoluteLocator, packageReplaceOptions) + if rf, ok := ret.Get(1).(func(string, string, string, map[string]string) *startosis_errors.InterpretationError); ok { + r1 = rf(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteLocator, packageReplaceOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*startosis_errors.InterpretationError) @@ -103,22 +147,24 @@ func (_m *MockPackageContentProvider) GetAbsoluteLocatorForRelativeLocator(packa return r0, r1 } -// MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAbsoluteLocatorForRelativeLocator' +// MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAbsoluteLocator' type MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call struct { *mock.Call } -// GetAbsoluteLocatorForRelativeLocator is a helper method to define mock.On call +// GetAbsoluteLocator is a helper method to define mock.On call // - packageId string +// - locatorOfModuleInWhichThisBuiltInIsBeingCalled string // - relativeOrAbsoluteLocator string // - packageReplaceOptions map[string]string -func (_e *MockPackageContentProvider_Expecter) GetAbsoluteLocatorForRelativeLocator(packageId interface{}, relativeOrAbsoluteLocator interface{}, packageReplaceOptions interface{}) *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call { - return &MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call{Call: _e.mock.On("GetAbsoluteLocatorForRelativeLocator", packageId, relativeOrAbsoluteLocator, packageReplaceOptions)} + +func (_e *MockPackageContentProvider_Expecter) GetAbsoluteLocatorForRelativeLocator(packageId interface{}, locatorOfModuleInWhichThisBuiltInIsBeingCalled interface{}, relativeOrAbsoluteLocator interface{}, packageReplaceOptions interface{}) *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call { + return &MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call{Call: _e.mock.On("GetAbsoluteLocator", packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, relativeOrAbsoluteLocator, packageReplaceOptions)} } -func (_c *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call) Run(run func(packageId string, relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string)) *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call { +func (_c *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call) Run(run func(packageId string, locatorOfModuleInWhichThisBuiltInIsBeingCalled string, relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string)) *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(map[string]string)) + run(args[0].(string), args[1].(string), args[2].(string), args[3].(map[string]string)) }) return _c } @@ -128,7 +174,7 @@ func (_c *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call) return _c } -func (_c *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call) RunAndReturn(run func(string, string, map[string]string) (string, *startosis_errors.InterpretationError)) *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call { +func (_c *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call) RunAndReturn(run func(string, string, string, map[string]string) (string, *startosis_errors.InterpretationError)) *MockPackageContentProvider_GetAbsoluteLocatorForRelativeLocator_Call { _c.Call.Return(run) return _c } @@ -351,50 +397,6 @@ func (_c *MockPackageContentProvider_GetOnDiskAbsolutePackagePath_Call) RunAndRe return _c } -// RefreshCache provides a mock function with given fields: currentPackageReplaceOptions -func (_m *MockPackageContentProvider) CloneReplacedPackagesIfNeeded(currentPackageReplaceOptions map[string]string) *startosis_errors.InterpretationError { - ret := _m.Called(currentPackageReplaceOptions) - - var r0 *startosis_errors.InterpretationError - if rf, ok := ret.Get(0).(func(map[string]string) *startosis_errors.InterpretationError); ok { - r0 = rf(currentPackageReplaceOptions) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*startosis_errors.InterpretationError) - } - } - - return r0 -} - -// MockPackageContentProvider_RefreshCache_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CloneReplacedPackagesIfNeeded' -type MockPackageContentProvider_RefreshCache_Call struct { - *mock.Call -} - -// RefreshCache is a helper method to define mock.On call -// - currentPackageReplaceOptions map[string]string -func (_e *MockPackageContentProvider_Expecter) RefreshCache(currentPackageReplaceOptions interface{}) *MockPackageContentProvider_RefreshCache_Call { - return &MockPackageContentProvider_RefreshCache_Call{Call: _e.mock.On("CloneReplacedPackagesIfNeeded", currentPackageReplaceOptions)} -} - -func (_c *MockPackageContentProvider_RefreshCache_Call) Run(run func(currentPackageReplaceOptions map[string]string)) *MockPackageContentProvider_RefreshCache_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(map[string]string)) - }) - return _c -} - -func (_c *MockPackageContentProvider_RefreshCache_Call) Return(_a0 *startosis_errors.InterpretationError) *MockPackageContentProvider_RefreshCache_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockPackageContentProvider_RefreshCache_Call) RunAndReturn(run func(map[string]string) *startosis_errors.InterpretationError) *MockPackageContentProvider_RefreshCache_Call { - _c.Call.Return(run) - return _c -} - // StorePackageContents provides a mock function with given fields: packageId, packageContent, overwriteExisting func (_m *MockPackageContentProvider) StorePackageContents(packageId string, packageContent io.Reader, overwriteExisting bool) (string, *startosis_errors.InterpretationError) { ret := _m.Called(packageId, packageContent, overwriteExisting) diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider/mock_package_content_provider.go b/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider/mock_package_content_provider.go index 65cbb3f723..9e4ac411c1 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider/mock_package_content_provider.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider/mock_package_content_provider.go @@ -76,7 +76,7 @@ func (provider *MockPackageContentProvider) GetModuleContents(fileInsidePackageU return string(fileContent), nil } -func (provider *MockPackageContentProvider) GetAbsoluteLocatorForRelativeLocator(parentModuleId string, relativeOrAbsoluteModulePath string, packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) { +func (provider *MockPackageContentProvider) GetAbsoluteLocator(packageId string, parentModuleId string, relativeOrAbsoluteModulePath string, packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) { if strings.HasPrefix(relativeOrAbsoluteModulePath, parentModuleId) { return "", startosis_errors.NewInterpretationError("Cannot use local absolute locators") } diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/package_content_provider.go b/core/server/api_container/server/startosis_engine/startosis_packages/package_content_provider.go index d9868b059f..8744e03257 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/package_content_provider.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/package_content_provider.go @@ -29,9 +29,10 @@ type PackageContentProvider interface { // ClonePackage clones the package with the given id and returns the absolute path on disk ClonePackage(packageId string) (string, *startosis_errors.InterpretationError) - // GetAbsoluteLocatorForRelativeLocator returns the absolute package path for a relative file path and replace the package path if - // there is a valid option in the packageReplaceOptions map - GetAbsoluteLocatorForRelativeLocator(packageId string, relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) + // GetAbsoluteLocator does: + // 1. if the given locator is relative, translates it to absolute using sourceModuleLocator (if it's already absolute, does nothing) + // 2. applies any replace rules, if they match the now-absolute locator + GetAbsoluteLocator(packageId string, locatorOfModuleInWhichThisBuiltInIsBeingCalled string, relativeOrAbsoluteLocator string, packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) // GetKurtosisYaml returns the package kurtosis.yml file content GetKurtosisYaml(packageAbsolutePathOnDisk string) (*yaml_parser.KurtosisYaml, *startosis_errors.InterpretationError) diff --git a/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_block_local_absolute_locators_testsuite_test.go b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_block_local_absolute_locators_testsuite_test.go new file mode 100644 index 0000000000..d31435a63c --- /dev/null +++ b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_block_local_absolute_locators_testsuite_test.go @@ -0,0 +1,70 @@ +package startosis_block_local_absolute_locators + +import ( + "context" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/starlark_run_config" + "os" + "path" + "testing" + + "github.com/kurtosis-tech/kurtosis-cli/golang_internal_testsuite/test_helpers" + "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + name = "startosis-block-local-absolute-locators" + emptyRunParams = "{}" + localAbsoluteLocatorNotAllowedMsg = "is referencing a file within the same package using absolute import syntax" + expectedRunOutput = "bar\n" +) + +type StartosisBlockLocalAbsoluteLocatorsTestSuite struct { + suite.Suite + enclaveCtx *enclaves.EnclaveContext + destroyEnclaveFunc func() error +} + +func TestStartosisBlockLocalAbsoluteLocatorsTestSuite(t *testing.T) { + suite.Run(t, new(StartosisBlockLocalAbsoluteLocatorsTestSuite)) +} + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) SetupTest() { + ctx := context.Background() + t := suite.T() + enclaveCtx, _, destroyEnclaveFunc, err := test_helpers.CreateEnclave(t, ctx, name) + require.NoError(t, err, "An error occurred creating an enclave") + suite.enclaveCtx = enclaveCtx + suite.destroyEnclaveFunc = destroyEnclaveFunc +} + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) TearDownTest() { + err := suite.destroyEnclaveFunc() + require.NoError(suite.T(), err, "Destroying the test suite's enclave process has failed, you will have to remove it manually") +} + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) RunPackage(ctx context.Context, packageRelativeDirpath string) (*enclaves.StarlarkRunResult, error) { + return suite.RunPackageWithParams(ctx, packageRelativeDirpath, emptyRunParams) +} + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) RunRemotePackage(ctx context.Context, remotePackage string) (*enclaves.StarlarkRunResult, error) { + return suite.enclaveCtx.RunStarlarkRemotePackageBlocking(ctx, remotePackage, starlark_run_config.NewRunStarlarkConfig()) +} + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) RunPackageWithParams(ctx context.Context, packageRelativeDirpath string, params string) (*enclaves.StarlarkRunResult, error) { + logrus.Infof("Executing Startosis package...") + + currentWorkingDirectory, err := os.Getwd() + require.Nil(suite.T(), err) + packageDirpath := path.Join(currentWorkingDirectory, packageRelativeDirpath) + + logrus.Debugf("Startosis package dirpath: %v", packageDirpath) + + return suite.enclaveCtx.RunStarlarkPackageBlocking( + ctx, + packageDirpath, + starlark_run_config.NewRunStarlarkConfig(starlark_run_config.WithSerializedParams(params)), + ) +} diff --git a/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_block_package_local_absolute_locator_test.go b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_block_package_local_absolute_locator_test.go new file mode 100644 index 0000000000..6b8e84510b --- /dev/null +++ b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_block_package_local_absolute_locator_test.go @@ -0,0 +1,24 @@ +package startosis_block_local_absolute_locators + +import ( + "context" + "github.com/stretchr/testify/require" +) + +const ( + packageWithLocalAbsoluteLocatorRelPath = "../../../starlark/local-absolute-locators/block-package-local-absolute-locator" +) + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) TestStartosisBlockPackageLocalAbsoluteLocator() { + ctx := context.Background() + runResult, err := suite.RunPackage(ctx, packageWithLocalAbsoluteLocatorRelPath) + + t := suite.T() + require.ErrorContains(t, err, localAbsoluteLocatorNotAllowedMsg) + require.NotNil(t, runResult) + + require.NotNil(t, runResult.InterpretationError) + require.Contains(t, runResult.InterpretationError.GetErrorMessage(), localAbsoluteLocatorNotAllowedMsg) + require.Empty(t, runResult.ValidationErrors) + require.Nil(t, runResult.ExecutionError) +} diff --git a/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_dont_block_child_importing_parent_file_test.go b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_dont_block_child_importing_parent_file_test.go new file mode 100644 index 0000000000..6ad1d1a2e0 --- /dev/null +++ b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_dont_block_child_importing_parent_file_test.go @@ -0,0 +1,24 @@ +package startosis_block_local_absolute_locators + +import ( + "context" + "github.com/stretchr/testify/require" +) + +const ( + packageWithChildPackageImportingParentPackageFileRelPath = "../../../starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package" +) + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) TestStartosisDontBlockChildImportingParentFile() { + ctx := context.Background() + runResult, err := suite.RunPackage(ctx, packageWithChildPackageImportingParentPackageFileRelPath) + + t := suite.T() + require.NoError(t, err) + require.NotNil(t, runResult) + + require.Nil(t, runResult.InterpretationError) + require.Empty(t, runResult.ValidationErrors) + require.Nil(t, runResult.ExecutionError) + require.Equal(t, expectedRunOutput, string(runResult.RunOutput)) +} diff --git a/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_dont_block_package_in_same_repository_test.go b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_dont_block_package_in_same_repository_test.go new file mode 100644 index 0000000000..91c927a74c --- /dev/null +++ b/internal_testsuites/golang/testsuite/startosis-block-local-absolute-locators_test/startosis_dont_block_package_in_same_repository_test.go @@ -0,0 +1,24 @@ +package startosis_block_local_absolute_locators + +import ( + "context" + "github.com/stretchr/testify/require" +) + +const ( + packageImportingFileFromAnotherPackageInSameRepositoryRelPath = "../../../starlark/local-absolute-locators/subpackages-in-same-repository/package1" +) + +func (suite *StartosisBlockLocalAbsoluteLocatorsTestSuite) TestStartosisDontBlockPackageInSameRepository() { + ctx := context.Background() + runResult, err := suite.RunPackage(ctx, packageImportingFileFromAnotherPackageInSameRepositoryRelPath) + + t := suite.T() + require.NoError(t, err) + require.NotNil(t, runResult) + + require.Nil(t, runResult.InterpretationError) + require.Empty(t, runResult.ValidationErrors) + require.Nil(t, runResult.ExecutionError) + require.Equal(t, expectedRunOutput, string(runResult.RunOutput)) +} diff --git a/internal_testsuites/golang/testsuite/startotis_idempotent_run_test/no_instruction_cached_test.go b/internal_testsuites/golang/testsuite/startosis_idempotency_test/no_instruction_cached_test.go similarity index 99% rename from internal_testsuites/golang/testsuite/startotis_idempotent_run_test/no_instruction_cached_test.go rename to internal_testsuites/golang/testsuite/startosis_idempotency_test/no_instruction_cached_test.go index 96a5506f3b..1df993e77e 100644 --- a/internal_testsuites/golang/testsuite/startotis_idempotent_run_test/no_instruction_cached_test.go +++ b/internal_testsuites/golang/testsuite/startosis_idempotency_test/no_instruction_cached_test.go @@ -1,4 +1,4 @@ -package startotis_idempotent_run_test +package startosis_persistent_directory_test import ( "context" diff --git a/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/file.star b/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/file.star new file mode 100644 index 0000000000..cf007eacf5 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/file.star @@ -0,0 +1 @@ +FOO = "bar" diff --git a/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/kurtosis.yml b/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/kurtosis.yml new file mode 100644 index 0000000000..c413349a84 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/kurtosis.yml @@ -0,0 +1 @@ +name: github.com/kurtosis-tech/block-package-local-absolute-locator diff --git a/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/main.star b/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/main.star new file mode 100644 index 0000000000..de57dcc7b5 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/block-package-local-absolute-locator/main.star @@ -0,0 +1,5 @@ +# This import should fail because we're importing a file within the package +file = import_module("github.com/kurtosis-tech/block-package-local-absolute-locator/file.star") + +def run(plan): + pass diff --git a/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/child-package/file.star b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/child-package/file.star new file mode 100644 index 0000000000..08b3c92b5f --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/child-package/file.star @@ -0,0 +1,5 @@ +# This import should be allowed because it's loaded in the child package +file_in_parent = import_module("github.com/kurtosis-tech/parent-package/file-in-parent.star") + +def run(plan): + plan.print(file_in_parent.FOO) diff --git a/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/child-package/kurtosis.yml b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/child-package/kurtosis.yml new file mode 100644 index 0000000000..70308475d1 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/child-package/kurtosis.yml @@ -0,0 +1 @@ +name: github.com/kurtosis-tech/block-package-local-absolute-locato diff --git a/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/file-in-parent.star b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/file-in-parent.star new file mode 100644 index 0000000000..cf007eacf5 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/file-in-parent.star @@ -0,0 +1 @@ +FOO = "bar" diff --git a/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/kurtosis.yml b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/kurtosis.yml new file mode 100644 index 0000000000..7def16cabb --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/kurtosis.yml @@ -0,0 +1,5 @@ +name: github.com/kurtosis-tech/parent-package +replace: + # Replacing the package with the 'local version' of the package + github.com/kurtosis-tech/child-package: ../child-package + \ No newline at end of file diff --git a/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/main.star b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/main.star new file mode 100644 index 0000000000..ffb8220df9 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/locator-in-child-package-points-to-parent-package/parent-package/main.star @@ -0,0 +1,6 @@ +# This import should not fail because we're importing a file from another package +file = import_module("github.com/kurtosis-tech/child-package/file.star") + +def run(plan): + file.run(plan) + pass diff --git a/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package1/kurtosis.yml b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package1/kurtosis.yml new file mode 100644 index 0000000000..49f2d13a48 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package1/kurtosis.yml @@ -0,0 +1,5 @@ +name: github.com/kurtosis-tech/subpackages-in-same-repository/package1 +replace: + # Replacing the package with the 'local version' of the package + github.com/kurtosis-tech/subpackages-in-same-repository/package2/: ../package2 + \ No newline at end of file diff --git a/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package1/main.star b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package1/main.star new file mode 100644 index 0000000000..8ffbb610a3 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package1/main.star @@ -0,0 +1,6 @@ +# This import should not fail because we're importing a file from another package on same repository +file = import_module("github.com/kurtosis-tech/subpackages-in-same-repository/package2/file.star") + +def run(plan): + file.run(plan) + pass diff --git a/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package2/file.star b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package2/file.star new file mode 100644 index 0000000000..cc23ed4a98 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package2/file.star @@ -0,0 +1,4 @@ +FOO = "bar" + +def run(plan): + plan.print(FOO) diff --git a/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package2/kurtosis.yml b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package2/kurtosis.yml new file mode 100644 index 0000000000..f9fcfa7e34 --- /dev/null +++ b/internal_testsuites/starlark/local-absolute-locators/subpackages-in-same-repository/package2/kurtosis.yml @@ -0,0 +1 @@ +name: github.com/kurtosis-tech/subpackages-in-same-repository/package2/