Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
slapos.core
Commits
0c398b4d
Commit
0c398b4d
authored
Mar 04, 2019
by
Alain Takoudjou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
grid.promise: add tests for promise cached information
parent
02bcc9a3
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
106 additions
and
10 deletions
+106
-10
slapos/grid/promise/__init__.py
slapos/grid/promise/__init__.py
+7
-8
slapos/tests/test_promise.py
slapos/tests/test_promise.py
+99
-2
No files found.
slapos/grid/promise/__init__.py
View file @
0c398b4d
...
@@ -94,7 +94,6 @@ class PromiseProcess(Process):
...
@@ -94,7 +94,6 @@ class PromiseProcess(Process):
self
.
_periodicity
=
None
self
.
_periodicity
=
None
self
.
cache_folder
=
os
.
path
.
join
(
self
.
partition_folder
,
self
.
cache_folder
=
os
.
path
.
join
(
self
.
partition_folder
,
PROMISE_CACHE_FOLDER_NAME
)
PROMISE_CACHE_FOLDER_NAME
)
mkdir_p
(
self
.
cache_folder
)
self
.
cache_file
=
os
.
path
.
join
(
self
.
cache_folder
,
self
.
getPromiseTitle
())
self
.
cache_file
=
os
.
path
.
join
(
self
.
cache_folder
,
self
.
getPromiseTitle
())
# XXX - remove old files used to store promise timestamp and periodicity
# XXX - remove old files used to store promise timestamp and periodicity
self
.
_cleanupDeprecated
()
self
.
_cleanupDeprecated
()
...
@@ -111,12 +110,6 @@ class PromiseProcess(Process):
...
@@ -111,12 +110,6 @@ class PromiseProcess(Process):
if
os
.
path
.
exists
(
periodicity_file
)
and
os
.
path
.
isfile
(
periodicity_file
):
if
os
.
path
.
exists
(
periodicity_file
)
and
os
.
path
.
isfile
(
periodicity_file
):
os
.
unlink
(
periodicity_file
)
os
.
unlink
(
periodicity_file
)
def
getNextPromiseTime
(
self
,
periodicity
):
"""
Return the next promise execution timestamp from now
"""
return
time
.
time
()
+
(
periodicity
*
60.0
)
def
getPromiseTitle
(
self
):
def
getPromiseTitle
(
self
):
return
os
.
path
.
splitext
(
self
.
name
)[
0
]
return
os
.
path
.
splitext
(
self
.
name
)[
0
]
...
@@ -171,6 +164,7 @@ class PromiseProcess(Process):
...
@@ -171,6 +164,7 @@ class PromiseProcess(Process):
promise_started
=
False
promise_started
=
False
if
self
.
uid
and
self
.
gid
:
if
self
.
uid
and
self
.
gid
:
dropPrivileges
(
self
.
uid
,
self
.
gid
,
logger
=
self
.
logger
)
dropPrivileges
(
self
.
uid
,
self
.
gid
,
logger
=
self
.
logger
)
mkdir_p
(
self
.
cache_folder
)
if
self
.
wrap_promise
:
if
self
.
wrap_promise
:
promise_instance
=
WrapPromise
(
self
.
argument_dict
)
promise_instance
=
WrapPromise
(
self
.
argument_dict
)
else
:
else
:
...
@@ -338,6 +332,7 @@ class PromiseLauncher(object):
...
@@ -338,6 +332,7 @@ class PromiseLauncher(object):
self
.
queue_result
=
MQueue
()
self
.
queue_result
=
MQueue
()
self
.
bang_called
=
False
self
.
bang_called
=
False
self
.
_skipped_amount
=
0
self
.
promise_output_dir
=
os
.
path
.
join
(
self
.
promise_output_dir
=
os
.
path
.
join
(
self
.
partition_folder
,
self
.
partition_folder
,
...
@@ -464,10 +459,12 @@ class PromiseLauncher(object):
...
@@ -464,10 +459,12 @@ class PromiseLauncher(object):
or
not
self
.
check_anomaly
and
not
promise_cache_dict
.
get
(
'is_tested'
):
or
not
self
.
check_anomaly
and
not
promise_cache_dict
.
get
(
'is_tested'
):
# promise is skipped, send empty result
# promise is skipped, send empty result
self
.
_writePromiseResult
(
PromiseQueueResult
())
self
.
_writePromiseResult
(
PromiseQueueResult
())
self
.
_skipped_amount
+=
1
return
return
if
not
self
.
force
and
(
promise_cache_dict
is
not
None
and
not
if
not
self
.
force
and
(
promise_cache_dict
is
not
None
and
not
self
.
isPeriodicityMatch
(
promise_cache_dict
.
get
(
'next_run_after'
))):
self
.
isPeriodicityMatch
(
promise_cache_dict
.
get
(
'next_run_after'
))):
# we won't start the promise process, just get the latest result
# we won't start the promise process, just get the latest result
self
.
_skipped_amount
+=
1
result
=
self
.
_loadPromiseResult
(
promise_process
.
getPromiseTitle
())
result
=
self
.
_loadPromiseResult
(
promise_process
.
getPromiseTitle
())
if
result
is
not
None
:
if
result
is
not
None
:
if
result
.
item
.
hasFailed
():
if
result
.
item
.
hasFailed
():
...
@@ -624,6 +621,8 @@ class PromiseLauncher(object):
...
@@ -624,6 +621,8 @@ class PromiseLauncher(object):
failed_promise_name
=
promise_name
failed_promise_name
=
promise_name
self
.
_updateFolderOwner
(
self
.
promise_output_dir
)
self
.
_updateFolderOwner
(
self
.
promise_output_dir
)
if
self
.
_skipped_amount
>
0
:
self
.
logger
.
info
(
"%s promises didn't need to be checked."
%
\
self
.
_skipped_amount
)
if
failed_promise_name
:
if
failed_promise_name
:
raise
PromiseError
(
"Promise %r failed."
%
failed_promise_name
)
raise
PromiseError
(
"Promise %r failed."
%
failed_promise_name
)
slapos/tests/test_promise.py
View file @
0c398b4d
...
@@ -36,7 +36,8 @@ import logging
...
@@ -36,7 +36,8 @@ import logging
from
datetime
import
datetime
,
timedelta
from
datetime
import
datetime
,
timedelta
import
six
import
six
from
six.moves
import
queue
from
six.moves
import
queue
from
slapos.grid.promise
import
interface
,
PromiseLauncher
,
PromiseProcess
,
PromiseError
from
slapos.grid.promise
import
(
interface
,
PromiseLauncher
,
PromiseProcess
,
PromiseError
,
PROMISE_CACHE_FOLDER_NAME
)
from
slapos.grid.promise.generic
import
(
GenericPromise
,
TestResult
,
AnomalyResult
,
from
slapos.grid.promise.generic
import
(
GenericPromise
,
TestResult
,
AnomalyResult
,
PromiseQueueResult
,
PROMISE_STATE_FOLDER_NAME
,
PromiseQueueResult
,
PROMISE_STATE_FOLDER_NAME
,
PROMISE_RESULT_FOLDER_NAME
,
PROMISE_RESULT_FOLDER_NAME
,
...
@@ -93,7 +94,7 @@ class TestSlapOSPromiseMixin(unittest.TestCase):
...
@@ -93,7 +94,7 @@ class TestSlapOSPromiseMixin(unittest.TestCase):
self
.
launcher
=
PromiseLauncher
(
self
.
launcher
=
PromiseLauncher
(
config
=
parameter_dict
,
config
=
parameter_dict
,
logger
=
logging
.
getLogger
(
'slapos.test.promise'
),
#
logger=logging.getLogger('slapos.test.promise'),
dry_run
=
dry_run
dry_run
=
dry_run
)
)
if
save_method
:
if
save_method
:
...
@@ -1213,6 +1214,102 @@ exit 1
...
@@ -1213,6 +1214,102 @@ exit 1
# no result returned by the promise
# no result returned by the promise
self
.
assertTrue
(
self
.
called
)
self
.
assertTrue
(
self
.
called
)
def
test_promise_cache
(
self
):
promise_name
=
'my_promise.py'
promise_file
=
os
.
path
.
join
(
self
.
plugin_dir
,
promise_name
)
self
.
configureLauncher
(
timeout
=
1
,
enable_anomaly
=
True
)
self
.
generatePromiseScript
(
promise_name
,
success
=
True
,
periodicity
=
0.01
,
with_anomaly
=
True
,
is_tested
=
False
)
# run promise, no failure
self
.
launcher
.
run
()
cache_folder
=
os
.
path
.
join
(
self
.
partition_dir
,
PROMISE_CACHE_FOLDER_NAME
)
cache_file
=
os
.
path
.
join
(
cache_folder
,
'my_promise'
)
self
.
assertTrue
(
os
.
path
.
exists
(
cache_folder
))
self
.
assertTrue
(
os
.
path
.
exists
(
cache_file
))
file_stat
=
os
.
stat
(
promise_file
)
with
open
(
cache_file
)
as
f
:
cache_dict
=
json
.
load
(
f
)
timestamp
=
cache_dict
.
pop
(
'timestamp'
)
info_dict
=
{
u'is_tested'
:
False
,
u'is_anomaly_detected'
:
True
,
u'periodicity'
:
0.01
,
u'next_run_after'
:
(
timestamp
+
0.01
*
60.0
),
u'module_file'
:
u'%s'
%
promise_file
,
u'module_file_mtime'
:
file_stat
.
st_mtime
,
}
# next run is in future
self
.
assertTrue
(
info_dict
[
'next_run_after'
]
>
time
.
time
())
self
.
assertEqual
(
info_dict
,
cache_dict
)
def
test_promise_cache_expire_with_periodicity
(
self
):
self
.
called
=
False
def
test_method
(
result
):
self
.
called
=
True
promise_name
=
'my_promise.py'
promise_file
=
os
.
path
.
join
(
self
.
plugin_dir
,
promise_name
)
self
.
configureLauncher
(
save_method
=
test_method
,
timeout
=
1
,
enable_anomaly
=
True
)
self
.
generatePromiseScript
(
promise_name
,
success
=
True
,
periodicity
=
0.01
,
with_anomaly
=
True
,
is_tested
=
False
)
# run promise, no failure
self
.
launcher
.
run
()
cache_folder
=
os
.
path
.
join
(
self
.
partition_dir
,
PROMISE_CACHE_FOLDER_NAME
)
cache_file
=
os
.
path
.
join
(
cache_folder
,
'my_promise'
)
self
.
assertTrue
(
os
.
path
.
exists
(
cache_folder
))
self
.
assertTrue
(
os
.
path
.
exists
(
cache_file
))
file_stat
=
os
.
stat
(
promise_file
)
with
open
(
cache_file
)
as
f
:
cache_dict
=
json
.
load
(
f
)
timestamp
=
cache_dict
.
pop
(
'timestamp'
)
info_dict
=
{
u'is_tested'
:
False
,
u'is_anomaly_detected'
:
True
,
u'periodicity'
:
0.01
,
u'next_run_after'
:
(
timestamp
+
0.01
*
60.0
),
u'module_file'
:
u'%s'
%
promise_file
,
u'module_file_mtime'
:
file_stat
.
st_mtime
,
}
self
.
assertEqual
(
info_dict
,
cache_dict
)
self
.
assertTrue
(
self
.
called
)
next_run_after
=
cache_dict
[
'next_run_after'
]
# periodicity not match
self
.
called
=
False
self
.
configureLauncher
(
save_method
=
test_method
,
timeout
=
1
,
enable_anomaly
=
True
)
self
.
launcher
.
run
()
self
.
assertFalse
(
self
.
called
)
with
open
(
cache_file
)
as
f
:
cache_dict
=
json
.
load
(
f
)
# no change!
current_timestamp
=
cache_dict
.
pop
(
'timestamp'
)
self
.
assertEqual
(
current_timestamp
,
timestamp
)
self
.
assertEqual
(
info_dict
,
cache_dict
)
time
.
sleep
(
1
)
# periodicity match
self
.
configureLauncher
(
save_method
=
test_method
,
timeout
=
1
,
enable_anomaly
=
True
)
self
.
launcher
.
run
()
# cached was updated
with
open
(
cache_file
)
as
f
:
cache_dict
=
json
.
load
(
f
)
new_timestamp
=
cache_dict
.
pop
(
'timestamp'
)
info_dict
=
{
u'is_tested'
:
False
,
u'is_anomaly_detected'
:
True
,
u'periodicity'
:
0.01
,
u'next_run_after'
:
(
new_timestamp
+
0.01
*
60.0
),
u'module_file'
:
u'%s'
%
promise_file
,
u'module_file_mtime'
:
file_stat
.
st_mtime
,
}
self
.
assertTrue
(
new_timestamp
>
timestamp
)
# next run is in future
self
.
assertTrue
(
cache_dict
[
'next_run_after'
]
>
next_run_after
)
self
.
assertEqual
(
info_dict
,
cache_dict
)
class
TestSlapOSGenericPromise
(
TestSlapOSPromiseMixin
):
class
TestSlapOSGenericPromise
(
TestSlapOSPromiseMixin
):
def
initialisePromise
(
self
,
promise_content
=
""
,
success
=
True
,
timeout
=
60
):
def
initialisePromise
(
self
,
promise_content
=
""
,
success
=
True
,
timeout
=
60
):
...
...
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