Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Melodic
melodic-frontend
Commits
73491aab
Commit
73491aab
authored
Jul 08, 2020
by
Alicja Reniewicz
Browse files
Merge branch 'ftt' into 'rc3.1'
Add Serverless Testing view See merge request
!5
parents
77c3c5df
57c0af12
Pipeline
#9003
passed with stages
in 9 minutes and 26 seconds
Changes
18
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/app/app-routing.module.ts
View file @
73491aab
...
...
@@ -35,6 +35,11 @@ const routes: Routes = [
canActivate
:
[
CommonUserAdminRoleGuard
]
},
{
path
:
'
serverless-testing
'
,
loadChildren
:
'
./serverless-testing/serverless-testing.module#ServerlessTestingModule
'
,
canActivate
:
[
CommonUserAdminRoleGuard
]
},
{
path
:
'
**
'
,
loadChildren
:
'
./user/user.module#UserModule
'
},
];
...
...
src/app/common-template/menu/menu.component.html
View file @
73491aab
...
...
@@ -29,6 +29,7 @@
<a
mat-list-item
routerLink=
"/process/details/offer"
><i
class=
"material-icons"
>
local_offer
</i>
Offers
</a>
<a
mat-list-item
routerLink=
"/simulation"
><i
class=
"material-icons"
>
toys
</i>
Simulation
</a>
<a
mat-list-item
routerLink=
"/serverless-testing"
><i
class=
"material-icons"
>
cloud_done
</i>
Serverless Testing
</a>
<a
*ngIf=
"isAdmin()"
mat-list-item
routerLink=
"/user"
><i
class=
"material-icons"
>
supervisor_account
</i>
Manage Users
</a>
<a
mat-list-item
routerLink=
"/user/password"
><i
class=
"material-icons"
>
visibility
</i>
Change Password
</a>
<a
mat-list-item
(click)=
"onLogOutClick(); snav.close()"
><i
class=
"material-icons"
>
eject
</i>
Log Out
</a>
...
...
src/app/serverless-testing/model/TestResultTree.ts
0 → 100644
View file @
73491aab
class
TestCaseResult
{
event
:
string
;
expectedOutput
:
string
;
actualOutput
:
string
;
message
:
string
;
result
:
string
;
duration
:
number
;
}
class
FunctionTestResult
{
functionName
:
string
;
duration
:
number
;
passed
:
number
;
failed
:
number
;
ignored
:
number
;
testCaseResults
:
Array
<
TestCaseResult
>
;
overallResult
:
string
;
failedAtStage
:
string
;
message
:
string
;
}
export
class
TestResultTree
{
testsRunResult
:
string
;
failedAtStage
:
string
;
message
:
string
;
duration
:
number
;
functionTestResults
:
Array
<
FunctionTestResult
>
;
}
src/app/serverless-testing/model/UploadYmlResponse.ts
0 → 100644
View file @
73491aab
export
class
UploadYmlResponse
{
testConfigfilePath
:
string
;
}
src/app/serverless-testing/route/serverless-testing-routing.module.ts
0 → 100644
View file @
73491aab
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
RouterModule
,
Routes
}
from
'
@angular/router
'
;
import
{
ServerlessTestingMainComponent
}
from
'
../serverless-testing-main/serverless-testing-main.component
'
;
const
routes
:
Routes
=
[
{
path
:
''
,
component
:
ServerlessTestingMainComponent
},
];
@
NgModule
({
imports
:
[
RouterModule
.
forChild
(
routes
)],
exports
:
[
RouterModule
]
})
export
class
ServerlessTestingRoutingModule
{
}
src/app/serverless-testing/serverless-testing-main/serverless-testing-main.component.html
0 → 100644
View file @
73491aab
<mat-card>
<mat-card-header>
<mat-card-title>
Test Serverless Functions
</mat-card-title>
<mat-card-subtitle>
Here you can test your serverless functions which have been deployed to the cloud.
Upload a test configuration file and then run the tests.
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<app-uploader-yml></app-uploader-yml>
<app-test-runner
[testsRunning]=
"testsRunning"
(runTestsEvent)=
"runTests()"
></app-test-runner>
<app-test-results
[results]=
"testResultTree"
></app-test-results>
</mat-card-content>
</mat-card>
src/app/serverless-testing/serverless-testing-main/serverless-testing-main.component.ts
0 → 100644
View file @
73491aab
import
{
AfterViewInit
,
Component
,
OnDestroy
,
OnInit
,
ViewChild
}
from
'
@angular/core
'
;
import
{
UploaderYmlComponent
}
from
'
../uploader-yml/uploader-yml.component
'
;
import
{
MatSnackBar
}
from
'
@angular/material
'
;
import
{
ServerlessTestingService
}
from
'
../service/serverless-testing.service
'
;
import
{
TestRunnerComponent
}
from
'
../test-runner/test-runner.component
'
;
import
{
TestResultsComponent
}
from
'
../test-results/test-results.component
'
;
import
{
TestResultTree
}
from
'
../model/TestResultTree
'
;
@
Component
({
selector
:
'
app-serverless-testing
'
,
templateUrl
:
'
./serverless-testing-main.component.html
'
,
styleUrls
:
[
'
../../app.component.css
'
]
})
export
class
ServerlessTestingMainComponent
implements
OnInit
,
AfterViewInit
,
OnDestroy
{
@
ViewChild
(
UploaderYmlComponent
)
uploaderYmlComponent
:
UploaderYmlComponent
;
@
ViewChild
(
TestRunnerComponent
)
testRunnerComponent
:
TestRunnerComponent
;
@
ViewChild
(
TestResultsComponent
)
testResultsComponent
:
TestResultsComponent
;
testsRunning
=
false
;
testResultTree
:
TestResultTree
=
null
;
constructor
(
private
snackBar
:
MatSnackBar
,
private
testingServerlessService
:
ServerlessTestingService
,
)
{
}
ngOnInit
()
{
localStorage
.
setItem
(
'
viewTitle
'
,
'
Serverless Testing
'
);
console
.
log
(
'
Component Serverless-testing-main initiated
'
);
}
ngAfterViewInit
():
void
{
}
ngOnDestroy
():
void
{
console
.
log
(
'
Component Serverless-testing-main destroyed
'
);
}
runTests
()
{
this
.
testsRunning
=
true
;
this
.
testingServerlessService
.
runTests
().
subscribe
(
response
=>
{
this
.
snackBar
.
open
(
'
Tests run ended.
'
,
'
Close
'
,
{
duration
:
10000
});
this
.
testResultTree
=
response
;
this
.
testsRunning
=
false
;
},
error
=>
{
this
.
testsRunning
=
false
;
console
.
log
(
error
);
this
.
snackBar
.
open
(
`
${
error
.
error
.
message
}
`
,
'
Close
'
,
{
duration
:
10000
});
},
);
}
}
src/app/serverless-testing/serverless-testing.module.ts
0 → 100644
View file @
73491aab
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
CommonModule
}
from
'
@angular/common
'
;
import
{
ServerlessTestingMainComponent
}
from
'
./serverless-testing-main/serverless-testing-main.component
'
;
import
{
AngularMaterialModule
}
from
'
../angular-material/angular-material.module
'
;
import
{
ServerlessTestingRoutingModule
}
from
'
./route/serverless-testing-routing.module
'
;
import
{
UploaderYmlComponent
}
from
'
./uploader-yml/uploader-yml.component
'
;
import
{
TestRunnerComponent
}
from
'
./test-runner/test-runner.component
'
;
import
{
TestResultsComponent
}
from
'
./test-results/test-results.component
'
;
@
NgModule
({
declarations
:
[
ServerlessTestingMainComponent
,
UploaderYmlComponent
,
TestRunnerComponent
,
TestResultsComponent
,
],
imports
:
[
CommonModule
,
ServerlessTestingRoutingModule
,
AngularMaterialModule
],
exports
:
[
],
entryComponents
:
[
]
})
export
class
ServerlessTestingModule
{
}
src/app/serverless-testing/service/serverless-testing.service.ts
0 → 100644
View file @
73491aab
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
HttpClient
,
HttpHeaders
}
from
'
@angular/common/http
'
;
import
{
tap
}
from
'
rxjs/operators
'
;
import
{
Observable
}
from
'
rxjs
'
;
import
{
AppConfigService
}
from
'
../../app-config/service/app-config.service
'
;
import
{
UploadYmlResponse
}
from
'
../model/UploadYmlResponse
'
;
import
{
TestResultTree
}
from
'
../model/TestResultTree
'
;
@
Injectable
({
providedIn
:
'
root
'
})
export
class
ServerlessTestingService
{
apiUrl
=
`
${
AppConfigService
.
settings
.
apiUrl
}
/auth/test`
;
constructor
(
private
http
:
HttpClient
)
{
}
uploadTestConfiguration
(
formData
:
FormData
):
Observable
<
UploadYmlResponse
>
{
const
uploadUrl
=
this
.
apiUrl
+
'
/upload
'
;
return
this
.
http
.
post
(
uploadUrl
,
formData
,
{
responseType
:
'
json
'
}).
pipe
(
tap
(
(
response
:
UploadYmlResponse
)
=>
{
console
.
log
(
'
Response:
'
,
response
);
},
error
=>
{
console
.
log
(
'
Error while uploading test configuration file:
'
,
error
);
}
));
}
runTests
():
Observable
<
TestResultTree
>
{
const
requestUrl
=
this
.
apiUrl
+
'
/run
'
;
return
this
.
http
.
post
(
requestUrl
,
null
,
{
responseType
:
'
json
'
}).
pipe
(
tap
(
(
response
:
TestResultTree
)
=>
{
console
.
log
(
'
Response:
'
,
response
);
},
error
=>
{
console
.
log
(
'
Error while running tests:
'
,
error
);
}
));
}
}
src/app/serverless-testing/test-results/test-results.component.css
0 → 100644
View file @
73491aab
div
{
padding-bottom
:
10px
;
}
pre
{
white-space
:
pre-wrap
;
}
src/app/serverless-testing/test-results/test-results.component.html
0 → 100644
View file @
73491aab
<div
id=
"test-results-id"
>
<mat-card>
<mat-card-header>
<mat-card-title>
Test Results
</mat-card-title>
</mat-card-header>
<mat-card-content>
<div
*ngIf=
"results == null; else resultsBlock"
>
There are currently no results.
</div>
<ng-template
#resultsBlock
>
<div
*ngIf=
"results.testsRunResult === 'FAILURE'; else resultTree"
>
<p>
An error occurred while running the tests at stage {{ results.failedAtStage }}.
</p>
<span>
Message
<pre>
{{ results.message }}
</pre></span>
</div>
<ng-template
#resultTree
>
<div>
Overall duration: {{ results.duration }} seconds
</div>
<mat-accordion>
<mat-expansion-panel
*ngFor=
"let functionTestResult of results.functionTestResults"
(opened)=
"panelOpenState = true"
(closed)=
"panelOpenState = false"
>
<mat-expansion-panel-header>
<mat-panel-title>
<span>
{{ functionTestResult.functionName }} ({{ functionTestResult.overallResult }})
</span>
</mat-panel-title>
</mat-expansion-panel-header>
<span>
Function name
<pre>
{{ functionTestResult.functionName }}
</pre></span>
<span>
Tests duration (seconds)
<pre>
{{ functionTestResult.duration }}
</pre></span>
<span>
Summary
<pre>
{{ functionTestResult.overallResult }}
</pre></span>
<span>
Number of passed tests
<pre>
{{ functionTestResult.passed }}
</pre></span>
<span>
Number of failed tests
<pre>
{{ functionTestResult.failed }}
</pre></span>
<span>
Number of ignored tests
<pre>
{{ functionTestResult.ignored }}
</pre></span>
<span
*ngIf=
"functionTestResult.failedAtStage"
>
Failed to run tests due to failure at stage
<pre>
{{ functionTestResult.failedAtStage }}
</pre>
</span>
<span
*ngIf=
"functionTestResult.message"
>
Message
<pre>
{{ functionTestResult.message }}
</pre></span>
<mat-accordion>
<div>
Test cases
</div>
<mat-expansion-panel
*ngFor=
"let testCaseResult of functionTestResult.testCaseResults; let i = index"
(opened)=
"panelOpenState = true"
(closed)=
"panelOpenState = false"
>
<mat-expansion-panel-header>
<mat-panel-title>
<span>
#{{ i+1 }} ({{ testCaseResult.result }})
</span>
</mat-panel-title>
</mat-expansion-panel-header>
<span>
Result
<pre>
{{ testCaseResult.result }}
</pre></span>
<span>
Duration
<pre>
{{ testCaseResult.duration }}
</pre></span>
<span>
Input
<pre>
{{ testCaseResult.event }}
</pre></span>
<span>
Expected output
<pre>
{{ testCaseResult.expectedOutput }}
</pre></span>
<span
*ngIf=
"testCaseResult.actualOutput"
>
Actual output
<pre>
{{ testCaseResult.actualOutput }}
</pre></span>
<span
*ngIf=
"testCaseResult.message"
>
Message
<pre>
{{ testCaseResult.message }}
</pre></span>
</mat-expansion-panel>
</mat-accordion>
</mat-expansion-panel>
</mat-accordion>
</ng-template>
</ng-template>
</mat-card-content>
</mat-card>
</div>
src/app/serverless-testing/test-results/test-results.component.ts
0 → 100644
View file @
73491aab
import
{
Component
,
Input
,
OnInit
}
from
'
@angular/core
'
;
import
{
TestResultTree
}
from
'
../model/TestResultTree
'
;
@
Component
({
selector
:
'
app-test-results
'
,
templateUrl
:
'
./test-results.component.html
'
,
styleUrls
:
[
'
./test-results.component.css
'
],
})
export
class
TestResultsComponent
implements
OnInit
{
@
Input
()
results
:
TestResultTree
;
panelOpenState
=
false
;
ngOnInit
():
void
{
}
}
src/app/serverless-testing/test-runner/test-runner.component.css
0 → 100644
View file @
73491aab
div
{
margin-bottom
:
10px
;
margin-top
:
10px
;
}
button
{
margin-left
:
var
(
--double-margin
);
}
src/app/serverless-testing/test-runner/test-runner.component.html
0 → 100644
View file @
73491aab
<div
id=
"test-runner-id"
>
<mat-card>
<mat-card-header>
<mat-card-title>
Run tests
</mat-card-title>
</mat-card-header>
<mat-card-content>
<div>
Click here to run the tests.
</div>
<button
mat-fab
(click)=
"runTests()"
>
<mat-icon>
play_arrow
</mat-icon>
</button>
<div
*ngIf=
"testsRunning"
>
<div>
Please wait. It may take a while...
</div>
<mat-progress-bar
color=
"primary"
mode=
"indeterminate"
></mat-progress-bar>
</div>
</mat-card-content>
</mat-card>
</div>
src/app/serverless-testing/test-runner/test-runner.component.ts
0 → 100644
View file @
73491aab
import
{
Component
,
EventEmitter
,
Input
,
OnInit
,
Output
}
from
'
@angular/core
'
;
@
Component
({
selector
:
'
app-test-runner
'
,
templateUrl
:
'
./test-runner.component.html
'
,
styleUrls
:
[
'
./test-runner.component.css
'
],
})
export
class
TestRunnerComponent
implements
OnInit
{
@
Input
()
testsRunning
:
boolean
;
@
Output
()
runTestsEvent
=
new
EventEmitter
();
ngOnInit
():
void
{
}
runTests
()
{
this
.
runTestsEvent
.
emit
();
}
}
src/app/serverless-testing/uploader-yml/uploader-yml.component.css
0 → 100644
View file @
73491aab
.file
{
display
:
flex
;
flex-wrap
:
wrap
;
align-items
:
center
;
}
.action-buttons
{
display
:
flex
;
flex-wrap
:
wrap
;
}
src/app/serverless-testing/uploader-yml/uploader-yml.component.html
0 → 100644
View file @
73491aab
<div
id=
"yml-uploader-div"
>
<mat-card>
<mat-card-header>
<mat-card-title>
YAML file Upload
</mat-card-title>
<mat-card-subtitle>
Upload the test configuration file here. Only .yml and .yaml files are accepted.
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div>
<input
type=
"file"
#ymlFile
id=
"fileUploadDialog"
(change)=
"onFileSelectionEvent($event)"
accept=
".yml,.yaml"
>
</div>
<div
class=
"file"
*ngIf=
"fileToUpload != null"
>
{{fileToUpload.name}} ({{convertBytesToSize(fileToUpload.size)}})
<div
class=
"action-buttons"
>
<button
mat-button
color=
"primary"
[disabled]=
"fileUploadDisabled"
(click)=
"onFileUploadEvent()"
title=
"Upload file"
>
<mat-icon>
file_upload
</mat-icon>
</button>
<button
mat-button
color=
"warn"
[disabled]=
"fileUploadDisabled"
(click)=
"removeSelectedFile()"
title=
"Remove selected file"
>
<mat-icon>
cancel
</mat-icon>
</button>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
src/app/serverless-testing/uploader-yml/uploader-yml.component.ts
0 → 100644
View file @
73491aab
import
{
Component
,
ElementRef
,
Input
,
OnInit
,
ViewChild
}
from
'
@angular/core
'
;
import
{
ServerlessTestingService
}
from
'
../service/serverless-testing.service
'
;
import
{
MatSnackBar
}
from
'
@angular/material
'
;
@
Component
({
selector
:
'
app-uploader-yml
'
,
templateUrl
:
'
./uploader-yml.component.html
'
,
styleUrls
:
[
'
./uploader-yml.component.css
'
],
})
export
class
UploaderYmlComponent
implements
OnInit
{
uploadInProgress
=
false
;
fileToUpload
:
File
=
null
;
total
:
number
=
null
;
@
ViewChild
(
'
ymlFile
'
)
ymlFile
:
ElementRef
;
constructor
(
private
snackBar
:
MatSnackBar
,
private
testingServerlessService
:
ServerlessTestingService
,
)
{
}
ngOnInit
():
void
{
}
@
Input
()
set
file
(
file
:
any
)
{
this
.
fileToUpload
=
file
;
this
.
total
=
this
.
fileToUpload
.
size
;
}
get
file
():
any
{
return
this
.
fileToUpload
;
}
convertBytesToSize
(
bytes
):
string
{
const
sizes
=
[
'
Bytes
'
,
'
KB
'
,
'
MB
'
,
'
GB
'
,
'
TB
'
];
if
(
bytes
===
0
)
{
return
'
0 Byte
'
;
}
const
i
=
Math
.
floor
(
Math
.
log
(
bytes
)
/
Math
.
log
(
1024
));
return
Math
.
round
(
bytes
/
Math
.
pow
(
1024
,
i
))
+
'
'
+
sizes
[
i
];
}
get
fileUploadDisabled
()
{
return
this
.
uploadInProgress
||
this
.
fileToUpload
==
null
;
}
onFileSelectionEvent
(
event
:
Event
)
{
this
.
fileToUpload
=
(
<
HTMLInputElement
>
event
.
target
).
files
[
0
];
console
.
log
(
'
Received event:
'
,
event
);
}
onFileUploadEvent
()
{
this
.
uploadInProgress
=
true
;
const
formData
:
FormData
=
new
FormData
();
formData
.
set
(
'
file
'
,
this
.
fileToUpload
,
this
.
fileToUpload
.
name
);
this
.
testingServerlessService
.
uploadTestConfiguration
(
formData
).
subscribe
(
response
=>
{
this
.
uploadInProgress
=
false
;
this
.
snackBar
.
open
(
`Successfully uploaded test config file:
${
this
.
fileToUpload
.
name
}
`
,
'
Close
'
,
{
duration
:
10000
},
);
this
.
removeSelectedFile
();
},
error
=>
{
this
.
uploadInProgress
=
false
;
console
.
log
(
error
);
this
.
snackBar
.
open
(
`Error while uploading:
${
error
.
error
.
message
}
`
,
'
Close
'
,
{
duration
:
10000
});
}
);
}
removeSelectedFile
()
{
this
.
fileToUpload
=
null
;
this
.
ymlFile
.
nativeElement
.
value
=
null
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment