Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions playground/backend/internal/code_processing/code_processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func Process(ctx context.Context, cacheService cache.Cache, lc *fs_tool.LifeCycl

go cancelCheck(pipelineLifeCycleCtx, pipelineId, cancelChannel, cacheService)

executorBuilder, err := builder.SetupExecutorBuilder(lc, utils.ReduceWhiteSpacesToSinge(pipelineOptions), sdkEnv)
executorBuilder, err := builder.SetupExecutorBuilder(lc.Paths, utils.ReduceWhiteSpacesToSinge(pipelineOptions), sdkEnv)
if err != nil {
_ = processSetupError(err, pipelineId, cacheService, pipelineLifeCycleCtx)
return
Expand Down Expand Up @@ -133,7 +133,7 @@ func Process(ctx context.Context, cacheService cache.Cache, lc *fs_tool.LifeCycl
// Compile
if sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_JAVA {
executor = executorBuilder.WithCompiler().
WithFileName(builder.GetFileNameFromFolder(lc.GetAbsoluteSourceFolderPath())).Build() // Need changed name for unit tests
WithFileName(builder.GetFileNameFromFolder(lc.Paths.AbsoluteSourceFileFolderPath, filepath.Ext(lc.Paths.SourceFileName))).Build() // Need changed name for unit tests
}
logger.Infof("%s: Compile() ...\n", pipelineId)
compileCmd := executor.Compile(pipelineLifeCycleCtx)
Expand All @@ -158,7 +158,7 @@ func Process(ctx context.Context, cacheService cache.Cache, lc *fs_tool.LifeCycl

// Run
if sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_JAVA {
executor, err = setJavaExecutableFile(lc, pipelineId, cacheService, pipelineLifeCycleCtx, executorBuilder, filepath.Join(appEnv.WorkingDir(), appEnv.PipelinesFolder()))
executor, err = setJavaExecutableFile(lc.Paths, pipelineId, cacheService, pipelineLifeCycleCtx, executorBuilder, filepath.Join(appEnv.WorkingDir(), appEnv.PipelinesFolder()))
if err != nil {
return
}
Expand All @@ -167,11 +167,11 @@ func Process(ctx context.Context, cacheService cache.Cache, lc *fs_tool.LifeCycl
runCmd := getExecuteCmd(&validationResults, &executor, pipelineLifeCycleCtx)
var runError bytes.Buffer
runOutput := streaming.RunOutputWriter{Ctx: pipelineLifeCycleCtx, CacheService: cacheService, PipelineId: pipelineId}
go readLogFile(pipelineLifeCycleCtx, ctx, cacheService, lc.GetAbsoluteLogFilePath(), pipelineId, stopReadLogsChannel, finishReadLogsChannel)
go readLogFile(pipelineLifeCycleCtx, ctx, cacheService, lc.Paths.AbsoluteLogFilePath, pipelineId, stopReadLogsChannel, finishReadLogsChannel)

if sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_GO {
// For go SDK all logs are placed to stdErr.
file, err := os.Create(lc.GetAbsoluteLogFilePath())
file, err := os.Create(lc.Paths.AbsoluteLogFilePath)
if err != nil {
// If some error with creating a log file do the same as with other SDK.
logger.Errorf("%s: error during create log file (go sdk): %s", pipelineId, err.Error())
Expand All @@ -197,7 +197,7 @@ func Process(ctx context.Context, cacheService cache.Cache, lc *fs_tool.LifeCycl
// Run step is finished, but code contains some error (divide by 0 for example)
if sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_GO {
// For Go SDK stdErr was redirected to the log file.
errData, err := os.ReadFile(lc.GetAbsoluteLogFilePath())
errData, err := os.ReadFile(lc.Paths.AbsoluteLogFilePath)
if err != nil {
logger.Errorf("%s: error during read errors from log file (go sdk): %s", pipelineId, err.Error())
}
Expand All @@ -222,8 +222,8 @@ func getExecuteCmd(valRes *sync.Map, executor *executors.Executor, ctxWithTimeou
}

// setJavaExecutableFile sets executable file name to runner (JAVA class name is known after compilation step)
func setJavaExecutableFile(lc *fs_tool.LifeCycle, id uuid.UUID, service cache.Cache, ctx context.Context, executorBuilder *executors.ExecutorBuilder, dir string) (executors.Executor, error) {
className, err := lc.ExecutableName(id, dir)
func setJavaExecutableFile(paths fs_tool.LifeCyclePaths, id uuid.UUID, service cache.Cache, ctx context.Context, executorBuilder *executors.ExecutorBuilder, dir string) (executors.Executor, error) {
className, err := paths.ExecutableName(id, dir)
if err != nil {
if err = processSetupError(err, id, service, ctx); err != nil {
return executorBuilder.Build(), err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func Test_Process(t *testing.T) {
t.Fatalf("error during prepare folders: %s", err.Error())
}
if tt.createExecFile {
_, _ = lc.CreateSourceCodeFile(tt.code)
_ = lc.CreateSourceCodeFile(tt.code)
}
if err = utils.SetToCache(tt.args.ctx, cacheService, tt.args.pipelineId, cache.Canceled, false); err != nil {
t.Fatal("error during set cancel flag to cache")
Expand All @@ -269,7 +269,7 @@ func Test_Process(t *testing.T) {

compileOutput, _ := cacheService.GetValue(tt.args.ctx, tt.args.pipelineId, cache.CompileOutput)
if tt.expectedCompileOutput != nil && strings.Contains(tt.expectedCompileOutput.(string), "%s") {
tt.expectedCompileOutput = fmt.Sprintf(tt.expectedCompileOutput.(string), lc.GetAbsoluteSourceFilePath())
tt.expectedCompileOutput = fmt.Sprintf(tt.expectedCompileOutput.(string), lc.Paths.AbsoluteSourceFilePath)
}
if !reflect.DeepEqual(compileOutput, tt.expectedCompileOutput) {
t.Errorf("processCode() set compileOutput: %s, but expectes: %s", compileOutput, tt.expectedCompileOutput)
Expand Down Expand Up @@ -535,7 +535,7 @@ func TestGetLastIndex(t *testing.T) {
func Test_setJavaExecutableFile(t *testing.T) {
pipelineId := uuid.New()
lc, _ := fs_tool.NewLifeCycle(pb.Sdk_SDK_JAVA, pipelineId, filepath.Join(os.Getenv("APP_WORK_DIR"), pipelinesFolder))
lc.ExecutableName = fakeExecutableName
lc.Paths.ExecutableName = fakeExecutableName
executorBuilder := executors.NewExecutorBuilder().WithRunner().WithCommand("fake cmd").ExecutorBuilder
type args struct {
lc *fs_tool.LifeCycle
Expand Down Expand Up @@ -572,7 +572,7 @@ func Test_setJavaExecutableFile(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := setJavaExecutableFile(tt.args.lc, tt.args.id, tt.args.service, tt.args.ctx, tt.args.executorBuilder, tt.args.dir)
got, err := setJavaExecutableFile(tt.args.lc.Paths, tt.args.id, tt.args.service, tt.args.ctx, tt.args.executorBuilder, tt.args.dir)
if (err != nil) != tt.wantErr {
t.Errorf("setJavaExecutableFile() error = %v, wantErr %v", err, tt.wantErr)
}
Expand Down Expand Up @@ -692,7 +692,7 @@ func prepareFiles(b *testing.B, pipelineId uuid.UUID, code string, sdk pb.Sdk) *
if err != nil {
b.Fatalf("error during prepare folders: %s", err.Error())
}
_, err = lc.CreateSourceCodeFile(code)
err = lc.CreateSourceCodeFile(code)
if err != nil {
b.Fatalf("error during prepare source code file: %s", err.Error())
}
Expand Down
2 changes: 0 additions & 2 deletions playground/backend/internal/environment/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,6 @@ func TestApplicationEnvs_PipelinesFolder(t *testing.T) {
workingDir string
cacheEnvs *CacheEnvs
pipelineExecuteTimeout time.Duration
launchSite string
projectId string
pipelinesFolder string
}
tests := []struct {
Expand Down
92 changes: 25 additions & 67 deletions playground/backend/internal/fs_tool/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,23 @@ const (
logFileName = "logs.log"
)

// Folder contains names of folders with executable and compiled files.
// For each SDK these values should be set depending on folders that need for the SDK.
type Folder struct {
BaseFolder string
SourceFileFolder string
ExecutableFileFolder string
// LifeCyclePaths contains all files/folders paths
type LifeCyclePaths struct {
SourceFileName string // {pipelineId}.{sourceFileExtension}
AbsoluteSourceFileFolderPath string // /path/to/workingDir/pipelinesFolder/{pipelineId}/src
AbsoluteSourceFilePath string // /path/to/workingDir/pipelinesFolder/{pipelineId}/src/{pipelineId}.{sourceFileExtension}
ExecutableFileName string // {pipelineId}.{executableFileExtension}
AbsoluteExecutableFileFolderPath string // /path/to/workingDir/pipelinesFolder/{pipelineId}/bin
AbsoluteExecutableFilePath string // /path/to/workingDir/pipelinesFolder/{pipelineId}/bin/{pipelineId}.{executableFileExtension}
AbsoluteBaseFolderPath string // /path/to/workingDir/pipelinesFolder/{pipelineId}
AbsoluteLogFilePath string // /path/to/workingDir/pipelinesFolder/{pipelineId}/logs.log
ExecutableName func(uuid.UUID, string) (string, error)
}

// Extension contains executable and compiled files' extensions.
// For each SDK these values should be set depending on SDK's extensions.
type Extension struct {
SourceFileExtension string
ExecutableFileExtension string
}

// LifeCycle is used for preparing folders and files to process code for one request.
// For each SDK folders (Folder) and extensions (Extension) should be set correctly.
// LifeCycle is used for preparing folders and files to process code for one code processing request.
type LifeCycle struct {
folderGlobs []string //folders that should be created to process code
Folder Folder
Extension Extension
ExecutableName func(uuid.UUID, string) (string, error)
pipelineId uuid.UUID
folderGlobs []string // folders that should be created to process code
Paths LifeCyclePaths
}

// NewLifeCycle returns a corresponding LifeCycle depending on the given SDK.
Expand All @@ -70,8 +64,8 @@ func NewLifeCycle(sdk pb.Sdk, pipelineId uuid.UUID, pipelinesFolder string) (*Li
}

// CreateFolders creates all folders which will be used for code execution.
func (l *LifeCycle) CreateFolders() error {
for _, folder := range l.folderGlobs {
func (lc *LifeCycle) CreateFolders() error {
for _, folder := range lc.folderGlobs {
err := os.MkdirAll(folder, fs.ModePerm)
if err != nil {
return err
Expand All @@ -81,8 +75,8 @@ func (l *LifeCycle) CreateFolders() error {
}

// DeleteFolders deletes all previously provisioned folders.
func (l *LifeCycle) DeleteFolders() error {
for _, folder := range l.folderGlobs {
func (lc *LifeCycle) DeleteFolders() error {
for _, folder := range lc.folderGlobs {
err := os.RemoveAll(folder)
if err != nil {
return err
Expand All @@ -92,30 +86,21 @@ func (l *LifeCycle) DeleteFolders() error {
}

// CreateSourceCodeFile creates an executable file (i.e. file.{sourceFileExtension}).
func (l *LifeCycle) CreateSourceCodeFile(code string) (string, error) {
if _, err := os.Stat(l.Folder.SourceFileFolder); os.IsNotExist(err) {
return "", err
func (lc *LifeCycle) CreateSourceCodeFile(code string) error {
if _, err := os.Stat(lc.Paths.AbsoluteSourceFileFolderPath); os.IsNotExist(err) {
return err
}

fileName := l.pipelineId.String() + l.Extension.SourceFileExtension
filePath := filepath.Join(l.Folder.SourceFileFolder, fileName)
filePath := lc.Paths.AbsoluteSourceFilePath
err := os.WriteFile(filePath, []byte(code), fileMode)
if err != nil {
return "", err
return err
}
return fileName, nil
}

// GetAbsoluteSourceFilePath returns absolute filepath to executable file (/path/to/workingDir/pipelinesFolder/{pipelineId}/src/{pipelineId}.{sourceFileExtension}).
func (l *LifeCycle) GetAbsoluteSourceFilePath() string {
fileName := l.pipelineId.String() + l.Extension.SourceFileExtension
filePath := filepath.Join(l.Folder.SourceFileFolder, fileName)
absoluteFilePath, _ := filepath.Abs(filePath)
return absoluteFilePath
return nil
}

// CopyFile copies a file with fileName from sourceDir to destinationDir.
func (l *LifeCycle) CopyFile(fileName, sourceDir, destinationDir string) error {
func (lc *LifeCycle) CopyFile(fileName, sourceDir, destinationDir string) error {
absSourcePath := filepath.Join(sourceDir, fileName)
absDestinationPath := filepath.Join(destinationDir, fileName)
sourceFileStat, err := os.Stat(absSourcePath)
Expand Down Expand Up @@ -144,30 +129,3 @@ func (l *LifeCycle) CopyFile(fileName, sourceDir, destinationDir string) error {
}
return nil
}

// GetAbsoluteExecutableFilePath returns absolute filepath to compiled file (/path/to/workingDir/pipelinesFolder/{pipelineId}/bin/{pipelineId}.{executableExtension}).
func (l *LifeCycle) GetAbsoluteExecutableFilePath() string {
fileName := l.pipelineId.String() + l.Extension.ExecutableFileExtension
filePath := filepath.Join(l.Folder.ExecutableFileFolder, fileName)
absoluteFilePath, _ := filepath.Abs(filePath)
return absoluteFilePath
}

// GetAbsoluteBaseFolderPath returns absolute path to executable folder (/path/to/workingDir/pipelinesFolder/{pipelineId}).
func (l *LifeCycle) GetAbsoluteBaseFolderPath() string {
absoluteFilePath, _ := filepath.Abs(l.Folder.BaseFolder)
return absoluteFilePath
}

// GetAbsoluteLogFilePath returns absolute path to the logs file (/path/to/workingDir/pipelinesFolder/{pipelineId}/logs.log)
func (l *LifeCycle) GetAbsoluteLogFilePath() string {
filePath := filepath.Join(l.Folder.BaseFolder, logFileName)
absoluteFilePath, _ := filepath.Abs(filePath)
return absoluteFilePath
}

// GetAbsoluteSourceFolderPath returns absolute path to executable folder (/path/to/workingDir/pipelinesFolder/{pipelineId}/src).
func (l *LifeCycle) GetAbsoluteSourceFolderPath() string {
absoluteFilePath, _ := filepath.Abs(l.Folder.SourceFileFolder)
return absoluteFilePath
}
Loading