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
Lu Xu
slapos.core
Commits
bcc1a6dc
Commit
bcc1a6dc
authored
Mar 06, 2012
by
Łukasz Nowak
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master' into performance-hack
parents
b33d1740
a45fee14
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
65 additions
and
20 deletions
+65
-20
master/bt5/vifib_base/PropertySheetTemplateItem/portal_property_sheets/SoftwareInstanceConstraint/connection_xml_valid_xml_constraint.xml
...nstanceConstraint/connection_xml_valid_xml_constraint.xml
+1
-1
master/bt5/vifib_base/PropertySheetTemplateItem/portal_property_sheets/SoftwareInstanceConstraint/sla_xml_valid_xml_constraint.xml
...ftwareInstanceConstraint/sla_xml_valid_xml_constraint.xml
+1
-1
master/bt5/vifib_base/bt/revision
master/bt5/vifib_base/bt/revision
+1
-1
master/bt5/vifib_slap/WorkflowTemplateItem/portal_workflow/slap_interaction_workflow/scripts/SalePackingList_cancelInstanciation.xml
..._workflow/scripts/SalePackingList_cancelInstanciation.xml
+3
-1
master/bt5/vifib_slap/bt/revision
master/bt5/vifib_slap/bt/revision
+1
-1
master/product/Vifib/tests/testVifibDefaultUseCase.py
master/product/Vifib/tests/testVifibDefaultUseCase.py
+23
-11
master/product/Vifib/tests/testVifibInstanceHostingRelatedDocument.py
...ct/Vifib/tests/testVifibInstanceHostingRelatedDocument.py
+3
-0
master/product/Vifib/tests/testVifibOpenOrderSimulation.py
master/product/Vifib/tests/testVifibOpenOrderSimulation.py
+3
-0
master/product/Vifib/tests/testVifibSlapComputerGetComputerPartitionList.py
...ib/tests/testVifibSlapComputerGetComputerPartitionList.py
+22
-4
master/product/Vifib/tests/testVifibSlapComputerPartitionLock.py
...product/Vifib/tests/testVifibSlapComputerPartitionLock.py
+5
-0
master/product/Vifib/tests/testVifibWebSite.py
master/product/Vifib/tests/testVifibWebSite.py
+2
-0
No files found.
master/bt5/vifib_base/PropertySheetTemplateItem/portal_property_sheets/SoftwareInstanceConstraint/connection_xml_valid_xml_constraint.xml
View file @
bcc1a6dc
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
expression
</string>
</key>
<key>
<string>
expression
</string>
</key>
<value>
<string>
python: context.getConnectionXml
()
</string>
</value>
<value>
<string>
python: context.getConnectionXml
AsDict() or True
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
id
</string>
</key>
<key>
<string>
id
</string>
</key>
...
...
master/bt5/vifib_base/PropertySheetTemplateItem/portal_property_sheets/SoftwareInstanceConstraint/sla_xml_valid_xml_constraint.xml
View file @
bcc1a6dc
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
expression
</string>
</key>
<key>
<string>
expression
</string>
</key>
<value>
<string>
python: context.getSlaXmlAsDict()
</string>
</value>
<value>
<string>
python: context.getSlaXmlAsDict()
or True
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
id
</string>
</key>
<key>
<string>
id
</string>
</key>
...
...
master/bt5/vifib_base/bt/revision
View file @
bcc1a6dc
408
409
\ No newline at end of file
\ No newline at end of file
master/bt5/vifib_slap/WorkflowTemplateItem/portal_workflow/slap_interaction_workflow/scripts/SalePackingList_cancelInstanciation.xml
View file @
bcc1a6dc
...
@@ -50,7 +50,8 @@
...
@@ -50,7 +50,8 @@
</item>
</item>
<item>
<item>
<key>
<string>
_body
</string>
</key>
<key>
<string>
_body
</string>
</key>
<value>
<string>
sale_packing_list = state_change[\'object\']\n
<value>
<string>
from DateTime import DateTime\n
sale_packing_list = state_change[\'object\']\n
\n
\n
setup_service_relative_url = sale_packing_list.portal_preferences.getPreferredInstanceSetupResource()\n
setup_service_relative_url = sale_packing_list.portal_preferences.getPreferredInstanceSetupResource()\n
destroy_service_relative_url = sale_packing_list.portal_preferences.getPreferredInstanceCleanupResource()\n
destroy_service_relative_url = sale_packing_list.portal_preferences.getPreferredInstanceCleanupResource()\n
...
@@ -61,6 +62,7 @@ for sale_packing_list_line in sale_packing_list.contentValues(\n
...
@@ -61,6 +62,7 @@ for sale_packing_list_line in sale_packing_list.contentValues(\n
# Slapgrid may be already handling this partition, so, create a destroy packing list\n
# Slapgrid may be already handling this partition, so, create a destroy packing list\n
# Clone the Packing List\n
# Clone the Packing List\n
destroy_sale_packing_list = sale_packing_list.Base_createCloneDocument(batch_mode=1)\n
destroy_sale_packing_list = sale_packing_list.Base_createCloneDocument(batch_mode=1)\n
destroy_sale_packing_list.setStartDate(DateTime())\n
# Delete all sub object except line clone\n
# Delete all sub object except line clone\n
destroy_sale_packing_list.deleteContent([x for x in destroy_sale_packing_list.contentIds() if x!=sale_packing_list_line.getId()])\n
destroy_sale_packing_list.deleteContent([x for x in destroy_sale_packing_list.contentIds() if x!=sale_packing_list_line.getId()])\n
# Update the remaining line\n
# Update the remaining line\n
...
...
master/bt5/vifib_slap/bt/revision
View file @
bcc1a6dc
598
599
\ No newline at end of file
\ No newline at end of file
master/product/Vifib/tests/testVifibDefaultUseCase.py
View file @
bcc1a6dc
...
@@ -6,7 +6,7 @@ from random import random
...
@@ -6,7 +6,7 @@ from random import random
from
slapos
import
slap
from
slapos
import
slap
from
zExceptions
import
Unauthorized
from
zExceptions
import
Unauthorized
from
DateTime
import
DateTime
from
DateTime
import
DateTime
from
Products.ERP5Type.tests.backportUnittest
import
skip
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
class
TestVifibDefaultUseCase
(
TestVifibSlapWebServiceMixin
):
class
TestVifibDefaultUseCase
(
TestVifibSlapWebServiceMixin
):
...
@@ -386,25 +386,25 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
...
@@ -386,25 +386,25 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
'planned'
,
'planned'
,
sale_invoice
.
getSimulationState
())
sale_invoice
.
getSimulationState
())
self
.
assertAlmostEquals
(
self
.
assertAlmostEquals
(
0.
836
,
sale_invoice
.
getTotalPrice
(),
3
)
0.
0
,
sale_invoice
.
getTotalPrice
(),
3
)
# 1 invoice line is expected
# 1 invoice line is expected
invoice_line_list
=
sale_invoice
.
contentValues
(
invoice_line_list
=
sale_invoice
.
contentValues
(
portal_type
=
"Invoice Line"
)
portal_type
=
"Invoice Line"
)
self
.
assertEquals
(
2
,
len
(
invoice_line_list
))
self
.
assertEquals
(
1
,
len
(
invoice_line_list
))
service_line
=
[
x
for
x
in
invoice_line_list
\
service_line
=
[
x
for
x
in
invoice_line_list
\
if
x
.
getResource
()
==
'service_module/vifib_instance_setup'
][
0
]
if
x
.
getResource
()
==
'service_module/vifib_instance_setup'
][
0
]
subscription_line
=
[
x
for
x
in
invoice_line_list
\
#
subscription_line = [x for x in invoice_line_list \
if
x
.
getResource
()
==
'service_module/vifib_instance_subscription'
][
0
]
#
if x.getResource() == 'service_module/vifib_instance_subscription'][0]
self
.
assertEquals
(
True
,
service_line
.
hasPrice
())
self
.
assertEquals
(
True
,
service_line
.
hasPrice
())
self
.
assertAlmostEquals
(
0
,
service_line
.
getPrice
(),
3
)
self
.
assertAlmostEquals
(
0
,
service_line
.
getPrice
(),
3
)
self
.
assertEquals
(
1
,
service_line
.
getQuantity
())
self
.
assertEquals
(
1
,
service_line
.
getQuantity
())
self
.
assertEquals
(
True
,
subscription_line
.
hasPrice
())
#
self.assertEquals(True, subscription_line.hasPrice())
self
.
assertAlmostEquals
(
0.836
,
subscription_line
.
getPrice
(),
3
)
#
self.assertAlmostEquals(0.836, subscription_line.getPrice(), 3)
self
.
assertEquals
(
1
,
subscription_line
.
getQuantity
())
#
self.assertEquals(1, subscription_line.getQuantity())
# 0 transaction line
# 0 transaction line
transaction_line_list
=
sale_invoice
.
contentValues
(
transaction_line_list
=
sale_invoice
.
contentValues
(
...
@@ -962,6 +962,8 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
...
@@ -962,6 +962,8 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getSource
())
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getSource
())
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getDestination
())
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getDestination
())
@
expectedFailure
# Hosting subscription is disabled, so scenarios are irrelevant
def
test_default_use_case
(
self
):
def
test_default_use_case
(
self
):
"""Test full default use case.
"""Test full default use case.
...
@@ -1049,15 +1051,23 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
...
@@ -1049,15 +1051,23 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
LoginWebUser
\
LoginWebUser
\
CheckWaitingInvoice
\
CheckWaitingInvoice
\
Tic
\
Tic
\
PayRegistrationPayment
\
CheckNoNewPayment
\
Tic
\
CheckPaidInvoice
\
LoginERP5TypeTestCase
\
LoginERP5TypeTestCase
\
CheckSiteConsistency
\
CheckSiteConsistency
\
Logout
\
Logout
\
'
'
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
play
(
self
)
sequence_list
.
play
(
self
)
# PayRegistrationPayment \
# Tic \
# CheckPaidInvoice \
def
stepCheckNoNewPayment
(
self
,
sequence
,
**
kw
):
"""
"""
self
.
assertEqual
(
None
,
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"Payment Transaction"
,
simulation_state
=
"planned"
))
def
stepCheckComplexInvoice
(
self
,
sequence
,
**
kw
):
def
stepCheckComplexInvoice
(
self
,
sequence
,
**
kw
):
"""
"""
...
@@ -1240,6 +1250,8 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
...
@@ -1240,6 +1250,8 @@ class TestVifibDefaultUseCase(TestVifibSlapWebServiceMixin):
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getSource
())
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getSource
())
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getDestination
())
self
.
assertEquals
(
'account_module/bank'
,
sale_line
.
getDestination
())
@
expectedFailure
# Hosting subscription is disabled, so scenarios are irrelevant
def
test_aggregated_use_case
(
self
):
def
test_aggregated_use_case
(
self
):
"""Test a more complex use case with many packing list agregated
"""Test a more complex use case with many packing list agregated
"""
"""
...
...
master/product/Vifib/tests/testVifibInstanceHostingRelatedDocument.py
View file @
bcc1a6dc
...
@@ -4,6 +4,7 @@ from testVifibSlapWebService import TestVifibSlapWebServiceMixin
...
@@ -4,6 +4,7 @@ from testVifibSlapWebService import TestVifibSlapWebServiceMixin
from
Products.ERP5Type.DateUtils
import
getClosestDate
from
Products.ERP5Type.DateUtils
import
getClosestDate
from
DateTime
import
DateTime
from
DateTime
import
DateTime
from
testVifibOpenOrderSimulation
import
generateTimeFrameList
from
testVifibOpenOrderSimulation
import
generateTimeFrameList
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
class
TestVifibInstanceHostingRelatedDocument
(
TestVifibSlapWebServiceMixin
):
class
TestVifibInstanceHostingRelatedDocument
(
TestVifibSlapWebServiceMixin
):
...
@@ -550,6 +551,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
...
@@ -550,6 +551,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
uid
=
sequence
[
'invoice_uid'
])
uid
=
sequence
[
'invoice_uid'
])
invoice
.
setStartDate
(
getClosestDate
(
target_date
=
DateTime
())
-
1
)
invoice
.
setStartDate
(
getClosestDate
(
target_date
=
DateTime
())
-
1
)
@
expectedFailure
# Subscription deliveries are not build for now.
def
test_OpenOrder_sale_packing_list
(
self
):
def
test_OpenOrder_sale_packing_list
(
self
):
"""
"""
Check that sale_packing_list is generated properly from simulation
Check that sale_packing_list is generated properly from simulation
...
...
master/product/Vifib/tests/testVifibOpenOrderSimulation.py
View file @
bcc1a6dc
...
@@ -2,6 +2,7 @@ import unittest
...
@@ -2,6 +2,7 @@ import unittest
from
Products.ERP5Type.tests.Sequence
import
SequenceList
from
Products.ERP5Type.tests.Sequence
import
SequenceList
from
Products.ERP5Type.DateUtils
import
getClosestDate
,
addToDate
from
Products.ERP5Type.DateUtils
import
getClosestDate
,
addToDate
from
testVifibSlapWebService
import
TestVifibSlapWebServiceMixin
from
testVifibSlapWebService
import
TestVifibSlapWebServiceMixin
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
from
DateTime.DateTime
import
DateTime
from
DateTime.DateTime
import
DateTime
...
@@ -186,6 +187,8 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
...
@@ -186,6 +187,8 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
self
.
assertEquals
(
3
,
self
.
assertEquals
(
3
,
len
(
simulation_movement_list
))
len
(
simulation_movement_list
))
@
expectedFailure
# Subscription deliveries are not build for now.
def
test_OpenOrder_request_changeSoftwareType
(
self
):
def
test_OpenOrder_request_changeSoftwareType
(
self
):
"""
"""
Check that requesting the same instance with a different software type
Check that requesting the same instance with a different software type
...
...
master/product/Vifib/tests/testVifibSlapComputerGetComputerPartitionList.py
View file @
bcc1a6dc
...
@@ -3,6 +3,7 @@ from Products.ERP5Type.tests.backportUnittest import skip
...
@@ -3,6 +3,7 @@ from Products.ERP5Type.tests.backportUnittest import skip
import
transaction
import
transaction
import
unittest
import
unittest
from
testVifibSlapWebService
import
TestVifibSlapWebServiceMixin
from
testVifibSlapWebService
import
TestVifibSlapWebServiceMixin
from
Products.DCWorkflow.DCWorkflow
import
ValidationFailed
class
TestVifibSlapComputerGetComputerPartitionList
(
TestVifibSlapWebServiceMixin
):
class
TestVifibSlapComputerGetComputerPartitionList
(
TestVifibSlapWebServiceMixin
):
########################################
########################################
...
@@ -690,11 +691,28 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
...
@@ -690,11 +691,28 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
def
stepDamageSoftwareInstanceXml
(
self
,
sequence
,
**
kw
):
def
stepDamageSoftwareInstanceXml
(
self
,
sequence
,
**
kw
):
software_instance
=
self
.
portal
.
portal_catalog
.
getResultValue
(
software_instance
=
self
.
portal
.
portal_catalog
.
getResultValue
(
uid
=
sequence
[
'software_instance_uid'
])
uid
=
sequence
[
'software_instance_uid'
])
software_instance
.
edit
(
text_content
=
"""
self
.
assertRaises
(
ValidationFailed
,
software_instance
.
edit
,
DAMAGED<BAD?xml XMLversion="1.0" encoding="utf-8"?>"""
)
text_content
=
"""DAMAGED<BAD?xml XMLversion="1.0" encoding="utf-8"?>"""
)
def
stepCheckDamageSoftwareInstanceSiteConsistency
(
self
,
sequence
,
**
kw
):
software_instance
=
self
.
portal
.
portal_catalog
.
getResultValue
(
uid
=
sequence
[
'software_instance_uid'
])
self
.
portal
.
portal_alarms
.
vifib_check_consistency
.
activeSense
()
transaction
.
commit
()
self
.
tic
()
consistency_error_list
=
self
.
portal
.
portal_alarms
.
vifib_check_consistency
\
.
Alarm_getConsistencyCheckReportLineList
()
self
.
assertEqual
(
1
,
len
(
consistency_error_list
))
consistency_error
=
consistency_error_list
[
0
]
self
.
assertEqual
(
consistency_error
.
getObject
().
getPath
(),
software_instance
.
getPath
())
self
.
assertTrue
(
'Sla XML is invalid'
in
str
(
consistency_error
.
getMessage
()))
self
.
assertTrue
(
self
.
portal
.
portal_alarms
.
vifib_check_consistency
.
sense
())
self
.
checkDivergency
()
def
test_Computer_getComputerPartitionList_damaged_xml
(
self
):
def
test_Computer_getComputerPartitionList_damaged_xml
(
self
):
"""Check that getComputerPartitionList works in case of damaged XML on instance."""
"""Check that getComputerPartitionList works in case of trying to damag XML,
which is refused."""
sequence_list
=
SequenceList
()
sequence_list
=
SequenceList
()
sequence_string
=
self
\
sequence_string
=
self
\
.
prepare_install_requested_computer_partition_sequence_string
+
"""
.
prepare_install_requested_computer_partition_sequence_string
+
"""
...
@@ -728,7 +746,7 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
...
@@ -728,7 +746,7 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
SlapLogout
SlapLogout
LoginERP5TypeTestCase
LoginERP5TypeTestCase
CheckSiteConsistency
Check
DamageSoftwareInstance
SiteConsistency
Logout
Logout
"""
"""
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
addSequenceString
(
sequence_string
)
...
...
master/product/Vifib/tests/testVifibSlapComputerPartitionLock.py
View file @
bcc1a6dc
...
@@ -2,6 +2,7 @@ from Products.ERP5Type.tests.Sequence import SequenceList
...
@@ -2,6 +2,7 @@ from Products.ERP5Type.tests.Sequence import SequenceList
import
unittest
import
unittest
from
testVifibSlapWebService
import
TestVifibSlapWebServiceMixin
from
testVifibSlapWebService
import
TestVifibSlapWebServiceMixin
from
zExceptions
import
Unauthorized
from
zExceptions
import
Unauthorized
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
class
TestVifibSlapComputerPartitionLock
(
TestVifibSlapWebServiceMixin
):
class
TestVifibSlapComputerPartitionLock
(
TestVifibSlapWebServiceMixin
):
...
@@ -47,6 +48,8 @@ class TestVifibSlapComputerPartitionLock(TestVifibSlapWebServiceMixin):
...
@@ -47,6 +48,8 @@ class TestVifibSlapComputerPartitionLock(TestVifibSlapWebServiceMixin):
portal_type
=
self
.
sale_packing_list_line_portal_type
)]
portal_type
=
self
.
sale_packing_list_line_portal_type
)]
self
.
assertEqual
(
0
,
len
(
delivery_line_list
))
self
.
assertEqual
(
0
,
len
(
delivery_line_list
))
@
expectedFailure
# Balance check is disabled so test is irrelevant
def
test_negative_person_balance_request
(
self
):
def
test_negative_person_balance_request
(
self
):
"""Locked person can not request
"""Locked person can not request
"""
"""
...
@@ -74,6 +77,8 @@ class TestVifibSlapComputerPartitionLock(TestVifibSlapWebServiceMixin):
...
@@ -74,6 +77,8 @@ class TestVifibSlapComputerPartitionLock(TestVifibSlapWebServiceMixin):
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
play
(
self
)
sequence_list
.
play
(
self
)
@
expectedFailure
# Balance check is disabled so test is irrelevant
def
test_negative_person_balance_request_slave
(
self
):
def
test_negative_person_balance_request_slave
(
self
):
"""Locked person can not request
"""Locked person can not request
"""
"""
...
...
master/product/Vifib/tests/testVifibWebSite.py
View file @
bcc1a6dc
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
##############################################################################
##############################################################################
import
unittest
import
unittest
from
VifibMixin
import
testVifibMixin
from
VifibMixin
import
testVifibMixin
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
HTTP_OK
=
200
HTTP_OK
=
200
MOVED_TEMPORARILY
=
302
MOVED_TEMPORARILY
=
302
...
@@ -70,6 +71,7 @@ class TestVifibWebSite(testVifibMixin):
...
@@ -70,6 +71,7 @@ class TestVifibWebSite(testVifibMixin):
response
.
getHeader
(
'content-type'
))
response
.
getHeader
(
'content-type'
))
self
.
assertTrue
(
"Website is under construction..."
in
response
.
getBody
())
self
.
assertTrue
(
"Website is under construction..."
in
response
.
getBody
())
@
expectedFailure
def
test_04_checkHostingAccess
(
self
):
def
test_04_checkHostingAccess
(
self
):
"""
"""
Test Hosting Access
Test Hosting Access
...
...
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