Skip to content

Commit 650ab0b

Browse files
shirish4Shirishsachinp328nevilm-lt
authored
Phx 3545 - Nucleus changes for go, java runner. (#201)
* golang runner integration * java integration * dockerfile changes * refactor constants * java api test execution * java api test execution * fixes and refactoring * framework version in constants * java 18 * fix comments * fix conflicts * fix conflicts * updated docker file * java jar name update * fix cyclomatic complexity * revert * fix git checks * dockerfile changes * fix blocklisting * resolve conflicts * fix dockerfile * refactor arguements * fix dockerfile * maven local repo path update * refactor dockerfile Co-authored-by: Shirish <[email protected]> Co-authored-by: Sachin Pandey <[email protected]> Co-authored-by: nevilm-lt <[email protected]>
1 parent ee636cc commit 650ab0b

File tree

11 files changed

+159
-54
lines changed

11 files changed

+159
-54
lines changed

build/nucleus/Dockerfile

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ ARG VERSION
1818
ENV VERSION=$VERSION
1919

2020
# Installing chromium so that all linux libs get automatically installed for running puppeteer tests
21-
RUN apt update && apt install -y git zstd chromium curl
21+
RUN apt update && apt install -y git zstd chromium curl unzip zip xmlstarlet build-essential
22+
RUN curl -LJO https://go.dev/dl/go1.18.3.linux-amd64.tar.gz
23+
RUN tar -C /usr/local -xzf go1.18.3.linux-amd64.tar.gz
2224

2325
COPY bundle /usr/local/bin/bundle
2426
RUN chmod +x /usr/local/bin/bundle
@@ -39,11 +41,18 @@ RUN npm i -g nyc@^15.1.0
3941

4042
RUN tar -zcf /custom-runners/custom-runners.tgz node_modules
4143
RUN rm -rf /tmp/custom-runners
42-
4344
RUN mkdir /home/nucleus
4445
RUN mkdir /home/nucleus/.nvm
4546
ENV NVM_DIR=/home/nucleus/.nvm
4647

48+
ENV GOROOT /usr/local/go
49+
ENV GOPATH /home/nucleus
50+
ENV PATH /usr/local/go/bin:/home/nucleus/bin:$PATH
51+
52+
COPY ./build/nucleus/golang/server /home/nucleus
53+
54+
RUN chmod 744 /home/nucleus/server
55+
4756
# install nvm for nucleus user
4857
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | /bin/bash
4958

@@ -52,4 +61,43 @@ WORKDIR /home/nucleus
5261
COPY --from=builder /nucleus/nucleus /usr/local/bin/
5362
# run the binary
5463
COPY ./build/nucleus/entrypoint.sh /
55-
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
64+
65+
RUN apt update -y && apt upgrade -y
66+
67+
RUN curl -s https://get.sdkman.io | bash
68+
RUN /bin/bash -c "source $HOME/.sdkman/bin/sdkman-init.sh;sdk install java 18.0.1-oracle"
69+
70+
ENV JAVA_HOME="/root/.sdkman/candidates/java/current"
71+
ENV PATH=$JAVA_HOME:$PATH
72+
ENV PATH=$JAVA_HOME/bin:$PATH
73+
74+
ARG MAVEN_VERSION=3.6.3
75+
76+
# Define a constant with the working directory
77+
ARG USER_HOME_DIR="/root"
78+
# Define the URL where maven can be downloaded from
79+
ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
80+
81+
# Create the directories, download maven, validate the download, install it, remove downloaded file and set links
82+
RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
83+
&& echo "Downlaoding maven" \
84+
&& curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
85+
\
86+
&& echo "Unziping maven" \
87+
&& tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
88+
\
89+
&& echo "Cleaning and setting links" \
90+
&& rm -f /tmp/apache-maven.tar.gz \
91+
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
92+
93+
# Define environmental variables required by Maven, like Maven_Home directory and where the maven repo is located
94+
ENV MAVEN_HOME /usr/share/maven
95+
RUN mkdir -p /home/nucleus/.m2
96+
97+
#update settings.xml file for new maven local repo location
98+
RUN xmlstarlet ed -O --inplace -N a='http://maven.apache.org/SETTINGS/1.0.0' -s /a:settings --type elem --name "localRepository" -v /home/nucleus/.m2/repository /usr/share/maven/conf/settings.xml
99+
100+
COPY ./build/nucleus/java/test-at-scale-java.jar /
101+
RUN curl -o /home/nucleus/junit-platform-console-standalone-1.8.2.jar https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/1.8.2/junit-platform-console-standalone-1.8.2.jar
102+
COPY ./build/nucleus/entrypoint.sh /
103+
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]

build/nucleus/golang/server

12 MB
Binary file not shown.

build/nucleus/java/test-at-scale-java.jar

Whitespace-only changes.

pkg/core/lifecycle.go

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
const (
2424
endpointPostTestResults = "http://localhost:9876/results"
2525
endpointPostTestList = "http://localhost:9876/test-list"
26+
languageJs = "javascript"
2627
)
2728

2829
// NewPipeline creates and returns a new Pipeline instance
@@ -56,7 +57,7 @@ func (pl *Pipeline) Start(ctx context.Context) (err error) {
5657
pl.Logger.Debugf("Payload for current task: %+v \n", *payload)
5758

5859
if pl.Cfg.CoverageMode {
59-
if err := pl.CoverageService.MergeAndUpload(ctx, payload); err != nil {
60+
if err = pl.CoverageService.MergeAndUpload(ctx, payload); err != nil {
6061
pl.Logger.Fatalf("error while merge and upload coverage files %v", err)
6162
}
6263
os.Exit(0)
@@ -211,11 +212,19 @@ func (pl *Pipeline) runOldVersion(ctx context.Context,
211212
return err
212213
}
213214

214-
cacheKey := fmt.Sprintf("%s/%s/%s/%s", tasConfig.Cache.Version, payload.OrgID, payload.RepoID, tasConfig.Cache.Key)
215+
cacheKey := ""
216+
217+
language := global.FrameworkLanguageMap[tasConfig.Framework]
218+
219+
if language == languageJs {
220+
cacheKey = fmt.Sprintf("%s/%s/%s/%s", tasConfig.Cache.Version, payload.OrgID, payload.RepoID, tasConfig.Cache.Key)
221+
}
222+
215223
pl.Logger.Infof("Tas yaml: %+v", tasConfig)
224+
216225
os.Setenv("REPO_CACHE_DIR", global.RepoCacheDir)
217226

218-
if tasConfig.NodeVersion != "" {
227+
if tasConfig.NodeVersion != "" && language == languageJs {
219228
nodeVersion := tasConfig.NodeVersion
220229
if nodeErr := pl.installNodeVersion(ctx, nodeVersion); nodeErr != nil {
221230
return nodeErr
@@ -250,6 +259,13 @@ func (pl *Pipeline) runTestExecutionV1(ctx context.Context,
250259
coverageDir string,
251260
secretMap map[string]string,
252261
taskPayload *TaskPayload, payload *Payload) error {
262+
blYml := pl.BlockTestService.GetBlocklistYMLV1(tasConfig)
263+
if errG := pl.BlockTestService.GetBlockTests(ctx, blYml, payload.BranchName); errG != nil {
264+
pl.Logger.Errorf("Unable to fetch blocklisted tests: %v", errG)
265+
errG = errs.New(errs.GenericErrRemark.Error())
266+
return errG
267+
}
268+
253269
executionResults, err := pl.TestExecutionService.RunV1(ctx, tasConfig, pl.Payload, coverageDir, secretMap)
254270
if err != nil {
255271
pl.Logger.Infof("Unable to perform test execution: %v", err)
@@ -291,20 +307,31 @@ func (pl *Pipeline) runDiscoveryV1(ctx context.Context,
291307
// discover test cases
292308
// mark status as passed
293309
// Upload cache once for other builds
310+
language := global.FrameworkLanguageMap[tasConfig.Framework]
311+
294312
if postErr := pl.TestDiscoveryService.UpdateSubmoduleList(ctx, payload.BuildID, 1); postErr != nil {
295313
return postErr
296314
}
297315

298316
g, errCtx := errgroup.WithContext(ctx)
299317

300-
g.Go(func() error {
301-
if errG := pl.CacheStore.Download(errCtx, cacheKey); errG != nil {
302-
pl.Logger.Errorf("Unable to download cache: %v", errG)
303-
errG = errs.New(errs.GenericErrRemark.Error())
304-
return errG
318+
if language == languageJs {
319+
g.Go(func() error {
320+
if errG := pl.CacheStore.Download(errCtx, cacheKey); errG != nil {
321+
pl.Logger.Errorf("Unable to download cache: %v", errG)
322+
errG = errs.New(errs.GenericErrRemark.Error())
323+
return errG
324+
}
325+
return nil
326+
})
327+
328+
err := pl.ExecutionManager.ExecuteInternalCommands(ctx, InstallRunners, global.InstallRunnerCmds, global.RepoDir, nil, nil)
329+
if err != nil {
330+
pl.Logger.Errorf("Unable to install custom runners %v", err)
331+
err = errs.New(errs.GenericErrRemark.Error())
332+
return err
305333
}
306-
return nil
307-
})
334+
}
308335

309336
pl.Logger.Infof("Identifying changed files ...")
310337
diffExists := true
@@ -338,12 +365,6 @@ func (pl *Pipeline) runDiscoveryV1(ctx context.Context,
338365
return err
339366
}
340367
}
341-
err = pl.ExecutionManager.ExecuteInternalCommands(ctx, InstallRunners, global.InstallRunnerCmds, global.RepoDir, nil, nil)
342-
if err != nil {
343-
pl.Logger.Errorf("Unable to install custom runners %v", err)
344-
err = errs.New(errs.GenericErrRemark.Error())
345-
return err
346-
}
347368

348369
pl.Logger.Debugf("Caching workspace")
349370

@@ -359,10 +380,12 @@ func (pl *Pipeline) runDiscoveryV1(ctx context.Context,
359380
err = &errs.StatusFailed{Remark: "Failed in discovering tests"}
360381
return err
361382
}
362-
if err = pl.CacheStore.Upload(ctx, cacheKey, tasConfig.Cache.Paths...); err != nil {
363-
pl.Logger.Errorf("Unable to upload cache: %v", err)
364-
err = errs.New(errs.GenericErrRemark.Error())
365-
return err
383+
if language == languageJs {
384+
if err = pl.CacheStore.Upload(ctx, cacheKey, tasConfig.Cache.Paths...); err != nil {
385+
pl.Logger.Errorf("Unable to upload cache: %v", err)
386+
err = errs.New(errs.GenericErrRemark.Error())
387+
return err
388+
}
366389
}
367390
taskPayload.Status = Passed
368391
pl.Logger.Debugf("Cache uploaded successfully")

pkg/core/models.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ type Oauth struct {
302302
// TASConfig represents the .tas.yml file
303303
type TASConfig struct {
304304
SmartRun bool `yaml:"smartRun"`
305-
Framework string `yaml:"framework" validate:"required,oneof=jest mocha jasmine"`
305+
Framework string `yaml:"framework" validate:"required,oneof=jest mocha jasmine golang junit"`
306306
Blocklist []string `yaml:"blocklist"`
307307
Postmerge *Merge `yaml:"postMerge" validate:"omitempty"`
308308
Premerge *Merge `yaml:"preMerge" validate:"omitempty"`
@@ -317,6 +317,7 @@ type TASConfig struct {
317317
Tier Tier `yaml:"tier" validate:"oneof=xsmall small medium large xlarge"`
318318
NodeVersion string `yaml:"nodeVersion" validate:"omitempty,semver"`
319319
ContainerImage string `yaml:"containerImage"`
320+
FrameworkVersion int `yaml:"frameworkVersion" validate:"omitempty"`
320321
Version string `yaml:"version" validate:"required"`
321322
}
322323

pkg/global/nucleusconstants.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ const (
3131
ModulePath = "MODULE_PATH"
3232
CacheVersion = "v1"
3333
PackageJSON = "package.json"
34+
ArgPattern = "--pattern"
35+
ArgConfig = "--config"
36+
ArgDiff = "--diff"
37+
ArgCommand = "--command"
38+
ArgLocator = "--locator-file"
39+
ArgFrameworVersion = "--frameworkVersion"
3440
DefaultTASVersion = "1.0.0"
3541
)
3642

@@ -39,6 +45,8 @@ var FrameworkRunnerMap = map[string]string{
3945
"jasmine": "./node_modules/.bin/jasmine-runner",
4046
"mocha": "./node_modules/.bin/mocha-runner",
4147
"jest": "./node_modules/.bin/jest-runner",
48+
"golang": "/home/nucleus/server",
49+
"junit": "java",
4250
}
4351

4452
// APIHostURLMap is map of git provider with there api url
@@ -58,3 +66,11 @@ var NeuronHost string
5866
func SetNeuronHost(host string) {
5967
NeuronHost = host
6068
}
69+
70+
var FrameworkLanguageMap = map[string]string{
71+
"jasmine": "javascript",
72+
"mocha": "javascript",
73+
"jest": "javascript",
74+
"golang": "golang",
75+
"junit": "java",
76+
}

pkg/service/coverage/coverage.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func New(execManager core.ExecutionManager,
6969

7070
}
7171

72-
//mergeCodeCoverageFiles merge all the coverage.json into single entity
72+
// mergeCodeCoverageFiles merge all the coverage.json into single entity
7373
func (c *codeCoverageService) mergeCodeCoverageFiles(ctx context.Context, commitDir, coverageManifestPath string, threshold bool) error {
7474
if _, err := os.Lstat(commitDir); os.IsNotExist(err) {
7575
c.logger.Errorf("coverage files not found, skipping merge")
@@ -78,7 +78,7 @@ func (c *codeCoverageService) mergeCodeCoverageFiles(ctx context.Context, commit
7878

7979
coverageFiles := make([]string, 0)
8080
if err := filepath.WalkDir(commitDir, func(path string, d fs.DirEntry, err error) error {
81-
//add all individual coverage json files
81+
// add all individual coverage json files
8282
if d.Name() == coverageJSONFileName {
8383
coverageFiles = append(coverageFiles, path)
8484
}

pkg/tasconfigmanager/setup.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ func (tc *tasConfigManager) validateYMLV1(ctx context.Context,
8181
return nil, err
8282
}
8383

84-
if tasConfig.Cache == nil {
84+
language := global.FrameworkLanguageMap[tasConfig.Framework]
85+
if tasConfig.Cache == nil && language == "javascript" {
8586
checksum, err := utils.ComputeChecksum(fmt.Sprintf("%s/%s", global.RepoDir, global.PackageJSON))
8687
if err != nil {
8788
tc.logger.Errorf("Error while computing checksum, error %v", err)

pkg/testdiscoveryservice/testdiscovery.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,22 @@ func (tds *testDiscoveryService) Discover(ctx context.Context,
5555
return err
5656
}
5757
impactAll := tds.shouldImpactAll(tasConfig, configFilePath, diff)
58-
args := []string{"--command", "discover"}
58+
59+
args := utils.GetArgs("discover", tasConfig, target)
60+
5961
if !impactAll {
6062
if len(diff) == 0 && diffExists {
6163
// empty diff; in PR, a commit added and then reverted to cause an overall empty PR diff
62-
args = append(args, "--diff")
64+
args = append(args, global.ArgDiff)
6365
} else {
6466
for k, v := range diff {
6567
// in changed files we only have added or modified files.
6668
if v != core.FileRemoved {
67-
args = append(args, "--diff", k)
69+
args = append(args, global.ArgDiff, k)
6870
}
6971
}
7072
}
7173
}
72-
if tasConfig.ConfigFile != "" {
73-
args = append(args, "--config", tasConfig.ConfigFile)
74-
}
75-
76-
for _, pattern := range target {
77-
args = append(args, "--pattern", pattern)
78-
}
7974
tds.logger.Debugf("Discovering tests at paths %+v", target)
8075

8176
cmd := exec.CommandContext(ctx, global.FrameworkRunnerMap[tasConfig.Framework], args...) //nolint:gosec
@@ -177,26 +172,26 @@ func (tds *testDiscoveryService) DiscoverV2(ctx context.Context,
177172
// discover all tests if tas.yml modified or smart run feature is set to false
178173
discoverAll := tasYmlModified || !tasConfig.SmartRun
179174

180-
args := []string{"--command", "discover"}
175+
args := []string{global.ArgCommand, "discover"}
181176
if !discoverAll {
182177
if len(diff) == 0 && diffExists {
183178
// empty diff; in PR, a commit added and then reverted to cause an overall empty PR diff
184-
args = append(args, "--diff")
179+
args = append(args, global.ArgDiff)
185180
} else {
186181
for k, v := range diff {
187182
// in changed files we only have added or modified files.
188183
if v != core.FileRemoved {
189-
args = append(args, "--diff", k)
184+
args = append(args, global.ArgDiff, k)
190185
}
191186
}
192187
}
193188
}
194189
if subModule.ConfigFile != "" {
195-
args = append(args, "--config", subModule.ConfigFile)
190+
args = append(args, global.ArgConfig, subModule.ConfigFile)
196191
}
197192

198193
for _, pattern := range target {
199-
args = append(args, "--pattern", pattern)
194+
args = append(args, global.ArgPattern, pattern)
200195
}
201196
tds.logger.Debugf("Discovering tests at paths %+v", target)
202197

pkg/testexecutionservice/testexecution.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,9 @@ func (tes *testExecutionService) buildCmdArgsV1(ctx context.Context,
308308
tasConfig *core.TASConfig,
309309
payload *core.Payload,
310310
target []string) ([]string, error) {
311-
args := []string{global.FrameworkRunnerMap[tasConfig.Framework], "--command", "execute"}
312-
if tasConfig.ConfigFile != "" {
313-
args = append(args, "--config", tasConfig.ConfigFile)
314-
}
315-
for _, pattern := range target {
316-
args = append(args, "--pattern", pattern)
317-
}
311+
args := []string{global.FrameworkRunnerMap[tasConfig.Framework]}
312+
313+
args = append(args, utils.GetArgs("execute", tasConfig, target)...)
318314

319315
if payload.LocatorAddress != "" {
320316
locatorFile, err := tes.getLocatorsFile(ctx, payload.LocatorAddress)
@@ -323,21 +319,23 @@ func (tes *testExecutionService) buildCmdArgsV1(ctx context.Context,
323319
tes.logger.Errorf("failed to get locator file, error: %v", err)
324320
return nil, err
325321
}
326-
args = append(args, "--locator-file", locatorFile)
322+
323+
args = append(args, global.ArgLocator, locatorFile)
327324
}
325+
328326
return args, nil
329327
}
330328

331329
func (tes *testExecutionService) buildCmdArgsV2(ctx context.Context,
332330
subModule *core.SubModule,
333331
payload *core.Payload,
334332
target []string) ([]string, error) {
335-
args := []string{global.FrameworkRunnerMap[subModule.Framework], "--command", "execute"}
333+
args := []string{global.FrameworkRunnerMap[subModule.Framework], global.ArgCommand, "execute"}
336334
if subModule.ConfigFile != "" {
337-
args = append(args, "--config", subModule.ConfigFile)
335+
args = append(args, global.ArgConfig, subModule.ConfigFile)
338336
}
339337
for _, pattern := range target {
340-
args = append(args, "--pattern", pattern)
338+
args = append(args, global.ArgPattern, pattern)
341339
}
342340

343341
if payload.LocatorAddress != "" {
@@ -347,7 +345,7 @@ func (tes *testExecutionService) buildCmdArgsV2(ctx context.Context,
347345
tes.logger.Errorf("failed to get locator file, error: %v", err)
348346
return nil, err
349347
}
350-
args = append(args, "--locator-file", locatorFile)
348+
args = append(args, global.ArgLocator, locatorFile)
351349
}
352350
return args, nil
353351
}

0 commit comments

Comments
 (0)