Commit 1f835cba authored by Rafael Monnerat's avatar Rafael Monnerat

Merge remote-tracking branch 'origin/operation-control'

Conflicts:
	master/bt5/slapos_cloud/bt/revision
	master/bt5/slapos_pdm/bt/revision
parents 2c7ba44e faf2b0b5
......@@ -52,6 +52,8 @@
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from DateTime import DateTime\n
\n
portal = context.getPortalObject()\n
\n
if software_product_reference is None:\n
......@@ -81,12 +83,20 @@ if len(product_list) > 1:\n
raise NotImplementedError(\'Several Software Product with the same title.\')\n
\n
software_release_list = product_list[0].getAggregateRelatedValueList()\n
\n
def sortkey(software_release):\n
publication_date = software_release.getEffectiveDate()\n
if publication_date:\n
if (publication_date - DateTime()) > 0:\n
return DateTime(\'1900/05/02\')\n
return publication_date\n
return software_release.getCreationDate()\n
\n
software_release_list = sorted(\n
software_release_list,\n
key=lambda software_release: software_release.getCreationDate(),\n
reverse=True,\n
key=sortkey, reverse=True,\n
)\n
\n
\n
return [software_release for software_release in software_release_list\n
if software_release.getValidationState() in\n
["published"]\n
......
......@@ -50,20 +50,11 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>software_release_url = context.getUrlString()\n
portal = context.getPortalObject()\n
network_list = []\n
\n
kw[\'portal_type\']=\'Computer Network\'\n
kw[\'validation_state\']=\'validated\'\n
\n
full_network_list = portal.portal_catalog(**kw)\n
for network in full_network_list:\n
computer_list = network.getSubordinationRelatedValueList()\n
for computer in computer_list:\n
if software_release_url in computer.Computer_getSoftwareReleaseUrlStringList():\n
network_list.append(network)\n
break\n
<value> <string>network_list = []\n
for computer in context.SoftwareRelease_getUsableComputerList():\n
network = computer.getSubordinationValue()\n
if network and not network in network_list:\n
network_list.append(network)\n
\n
return network_list\n
</string> </value>
......
......@@ -50,10 +50,13 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>software_installation_list = context.portal_catalog(url_string=context.getUrlString(),\n
portal_type=\'Software Installation\', validation_state=\'validated\')\n
<value> <string>kw[\'portal_type\'] = \'Software Installation\'\n
kw[\'validation_state\'] = \'validated\'\n
kw[\'url_string\'] = context.getUrlString()\n
\n
software_installation_list = context.portal_catalog(**kw)\n
computer_list = []\n
allocation_scope_list = [\'open/personal\', \'open/public\', \'open/frien\']\n
allocation_scope_list = [\'open/personal\', \'open/public\', \'open/friend\']\n
for software_installation in software_installation_list:\n
computer = software_installation.getAggregateValue()\n
if software_installation.getSlapState() == \'start_requested\' and \\\n
......
......@@ -115,6 +115,7 @@
<string>my_crawling_scope</string>
<string>my_crawling_depth</string>
<string>my_update_frequency</string>
<string>my_effective_date</string>
</list>
</value>
</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default_now</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_effective_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default_now</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_effective_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Document_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -15,8 +15,10 @@
<string>hide_rows_on_no_search_criterion</string>
<string>list_method</string>
<string>portal_types</string>
<string>search</string>
<string>search_columns</string>
<string>select</string>
<string>sort_columns</string>
<string>title</string>
</list>
</value>
......@@ -130,6 +132,10 @@
</list>
</value>
</item>
<item>
<key> <string>search</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value>
......@@ -145,6 +151,12 @@
<key> <string>select</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
......
......@@ -149,7 +149,8 @@ class TestSoftwareReleaseListFromSoftwareProduct(testSlapOSMixin):
software_release1 = self._makeSoftwareRelease(new_id)
software_release1.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1-%s.cfg' % new_id
url_string='http://example.org/1-%s.cfg' % new_id,
effective_date=(DateTime() + 5)
)
software_release1.publish()
software_release2 = self._makeSoftwareRelease(self.generateNewId())
......@@ -185,14 +186,16 @@ class TestSoftwareReleaseListFromSoftwareProduct(testSlapOSMixin):
software_release2.publish()
software_release2.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2-%s.cfg' % new_id
url_string='http://example.org/2-%s.cfg' % new_id,
effective_date=(DateTime() - 2)
)
# Newest software release
software_release1 = self._makeSoftwareRelease(new_id)
software_release1.publish()
software_release1.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1-%s.cfg' % new_id
url_string='http://example.org/1-%s.cfg' % new_id,
effective_date=DateTime()
)
self.tic()
......@@ -280,6 +283,7 @@ class TestSlapOSUpgradeHostingSubscription(BaseTestSlapOSMixin):
True)
self.portal.portal_workflow._jumpToStateFor(hosting_subscription, 'destroy_requested')
self.tic()
self.assertEqual(hosting_subscription.HostingSubscription_isUpgradable(),
False)
\ No newline at end of file
......@@ -32,7 +32,9 @@
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value> <int>1</int> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
......@@ -42,9 +44,7 @@
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value>
<none/>
</value>
<value> <int>30</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
......
......@@ -26,13 +26,15 @@
<key> <string>periodicity_hour</string> </key>
<value>
<tuple>
<int>1</int>
<int>0</int>
</tuple>
</value>
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value> <int>1</int> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
......@@ -44,9 +46,7 @@
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value>
<none/>
</value>
<value> <int>30</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
......
......@@ -63,20 +63,21 @@ software_instance_list = context.portal_catalog(\n
# XXX slap_state=["start_requested", "stop_requested"],\n
default_aggregate_uid=None,\n
select_dict=select_dict,\n
left_join_list=select_dict.keys()\n
left_join_list=select_dict.keys(),\n
group_by="specialise_uid"\n
)\n
\n
#Get the list of concerned Hosting Subscription reference\n
hs_reference_list = set([si.getSpecialiseReference() for si in software_instance_list \n
hs_reference_list = [si.getSpecialiseReference() for si in software_instance_list \n
if si.getSlapState() in [\'start_requested\', \'stop_requested\']\n
])\n
]\n
\n
if len(hs_reference_list) > 0:\n
portal.portal_catalog.searchAndActivate(\n
portal_type=\'Hosting Subscription\',\n
validation_state=\'validated\',\n
reference=hs_reference_list,\n
method_id=\'HostingSubscription_checkSofwareInstanceState\',\n
method_id=\'HostingSubscription_checkSofwareInstanceAllocationState\',\n
activate_kw = {\'tag\':tag}\n
)\n
\n
......
......@@ -59,6 +59,8 @@ if source_project_value.getPortalType() == "Computer":\n
destination_decision = source_project_value.getSourceAdministration()\n
elif source_project_value.getPortalType() == "Software Instance":\n
destination_decision = source_project_value.getSpecialiseValue().getDestinationSection()\n
elif source_project_value.getPortalType() == "Hosting Subscription":\n
destination_decision = source_project_value.getDestinationSection()\n
else:\n
destination_decision = None\n
\n
......@@ -66,6 +68,8 @@ if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):\n
# Stop ticket creation\n
return\n
\n
if not title.startswith(\'[MONITORING]\'):\n
title = \'[MONITORING] \' + title\n
support_request_in_progress = portal.portal_catalog.getResultValue(\n
portal_type = \'Support Request\',\n
title = title,\n
......@@ -74,6 +78,8 @@ support_request_in_progress = portal.portal_catalog.getResultValue(\n
)\n
\n
if support_request_in_progress is None:\n
ressource = portal.service_module.\\\n
slapos_crm_monitoring.getRelativeUrl()\n
support_request = portal.\\\n
support_request_module.\\\n
slapos_crm_support_request_template_for_monitoring.\\\n
......@@ -83,7 +89,8 @@ if support_request_in_progress is None:\n
description = description,\n
start_date = DateTime(),\n
destination_decision=destination_decision,\n
source_project_value = source_relative_url\n
source_project_value = source_relative_url,\n
ressource=ressource\n
)\n
support_request.validate()\n
\n
......
......@@ -80,18 +80,9 @@ if not is_service_provider:\n
\n
# Create a ticket (or re-open it) for this issue!\n
support_request = None\n
request_title = \'Allocation scope has been changed for %s\' % computer_reference\n
request_title = \'[MONITORING] Allocation scope has been changed for %s\' % computer_reference\n
request_description = \'Allocation scope has been changed back to \' \\\n
\'open/personal for %s\' % computer_reference\n
message_title = \'We have changed allocation scope for %s\' % computer_reference\n
notification_reference = \'slapos-crm-computer_allocation_scope.notification\'\n
notification_message = portal.portal_notifications.getDocumentValue(\n
reference=notification_reference)\n
mapping_dict = {\'computer_title\':computer.getTitle(),\n
\'computer_id\':computer_reference,\n
\'allocation_scope\':allocation_scope}\n
message = notification_message.asText(\n
substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
\n
support_request_url = context.Base_generateSupportRequestForSlapOS(\n
request_title,\n
......@@ -114,6 +105,26 @@ if not is_service_provider:\n
# Existing ticket not found, can not create event for the moment\n
return\n
\n
# Send notification message\n
message_title = \'We have changed allocation scope for %s\' % computer_reference\n
notification_reference = \'slapos-crm-computer_allocation_scope.notification\'\n
notification_message = portal.portal_notifications.getDocumentValue(\n
reference=notification_reference)\n
if notification_message is None:\n
message = """Dear user,\n
%s.\n
Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.\n
\n
Regards,\n
\n
The slapos team""" % request_description\n
else:\n
mapping_dict = {\'computer_title\':computer.getTitle(),\n
\'computer_id\':computer_reference,\n
\'allocation_scope\':allocation_scope}\n
message = notification_message.asText(\n
substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
\n
support_request.SupportRequest_trySendNotificationMessage(message_title,\n
message, person.getRelativeUrl())\n
</string> </value>
......
......@@ -62,29 +62,81 @@ if portal.ERP5Site_isSupportRequestCreationClosed():\n
return\n
\n
reference = context.getReference()\n
computer_title = context.getTitle()\n
ticket_title = "[MONITORING] Lost contact with computer %s" % reference\n
description = ""\n
should_notify = True\n
last_contact = "No Contact Information"\n
\n
memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n
key_prefix=\'slap_tool\',\n
plugin_path=\'portal_memcached/default_memcached_plugin\')\n
\n
try:\n
d = memcached_dict[reference]\n
d = json.loads(d)\n
last_contact = DateTime(d.get(\'created_at\'))\n
if (DateTime() - last_contact) > 1:\n
description = "The Computer %s (%s) has not contacted the server for more than 24 hours" \\\n
"(last contact date: %s)" % (computer_title, reference, last_contact)\n
else:\n
should_notify = False\n
except KeyError:\n
return context.Base_generateSupportRequestForSlapOS(\n
"No information about %s" % reference,\n
"%s has not contacted the server (No Contact Information)" % reference,\n
ticket_title = "[MONITORING] No information about %s" % reference\n
description = "The Computer %s (%s) has not contacted the server (No Contact Information)" % (\n
computer_title, reference)\n
\n
\n
if should_notify:\n
support_request_url = context.Base_generateSupportRequestForSlapOS(\n
ticket_title,\n
description,\n
context.getRelativeUrl()\n
)\n
\n
support_request = None\n
person = context.getSourceAdministrationValue(portal_type="Person")\n
if not person:\n
return support_request_url\n
\n
if support_request_url:\n
support_request = portal.restrictedTraverse(support_request_url, None)\n
else:\n
# XXX - the support request might already exists\n
support_request = portal.portal_catalog.getResultValue(\n
portal_type = \'Support Request\',\n
title = ticket_title,\n
simulation_state = \'validated\',\n
source_project_uid = context.getUid()\n
)\n
if support_request is None:\n
# Existing ticket not found, can not create event for the moment\n
return support_request_url\n
\n
# Send Notification message\n
notification_reference = \'slapos-crm-computer_check_state.notification\'\n
notification_message = portal.portal_notifications.getDocumentValue(\n
reference=notification_reference)\n
if notification_message is None:\n
message = """Dear user,\n
%s.\n
Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.\n
\n
d = json.loads(d)\n
last_contact = DateTime(d.get(\'created_at\'))\n
Regards,\n
\n
if (DateTime() - last_contact) > 1:\n
return context.Base_generateSupportRequestForSlapOS(\n
"Lost contact with %s" % reference,\n
"%s has not contacted the server for more than 24 hours (last contact date: %s)" % (reference, last_contact),\n
context.getRelativeUrl()\n
)\n
The slapos team""" % description\n
else:\n
mapping_dict = {\'computer_title\':context.getTitle(),\n
\'computer_id\':reference,\n
\'last_contact\':last_contact}\n
message = notification_message.asText(\n
substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
\n
support_request.SupportRequest_trySendNotificationMessage(\n
ticket_title.replace(\'[MONITORING] \', \'\'),\n
message, person.getRelativeUrl(), 5)\n
\n
return support_request_url\n
]]></string> </value>
......
......@@ -88,11 +88,10 @@ for instance in software_instance_list:\n
\n
if has_unallocated_instance and has_newest_allocated_instance:\n
return context.Base_generateSupportRequestForSlapOS(\n
"Hosting Subscription %s (%s) is partially allocated" % (hs_title,\n
hosting_subscription.getReference()),\n
"%s has allocated instance(s) but, instance %s (%s) has been unallocated for more than 4 hours." % (\n
"Hosting Subscription %s is partially allocated" % hs_title,\n
"%s has allocated instance(s) but, the instance %s (%s) has been unallocated for more than 4 hours." % (\n
hs_title, failing_instance.getTitle(), failing_instance.getAbsoluteUrl()),\n
source_instance.getRelativeUrl())\n
hosting_subscription.getRelativeUrl())\n
else:\n
return\n
......@@ -105,7 +104,7 @@ else:\n
</item>
<item>
<key> <string>id</string> </key>
<value> <string>HostingSubscription_checkSofwareInstanceState</string> </value>
<value> <string>HostingSubscription_checkSofwareInstanceAllocationState</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -62,7 +62,7 @@ last_event = context.portal_catalog.getResultValue(\n
sort_on=[(\'delivery.start_date\', \'DESC\')],\n
)\n
if last_event and \\\n
(DateTime() - last_event.getStartDate() < 1):\n
(DateTime() - last_event.getStartDate() < interval_of_day):\n
# User has already been notified this last 24h.\n
return\n
event = portal.event_module.slapos_crm_web_message_template.\\\n
......@@ -77,13 +77,15 @@ event.edit(\n
)\n
event.stop()\n
event.deliver()\n
\n
return event\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>message_title, message, source_relative_url</string> </value>
<value> <string>message_title, message, source_relative_url, interval_of_day=1</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -43,13 +43,8 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
def _cancelTestSupportRequestList(self):
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
title="Test Support Request %",
simulation_state="validated"):
support_request.invalidate()
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
title="Allocation scope has been changed for TESTCOMPT%",
simulation_state="suspended"):
title="%Test Support Request %",
simulation_state=["validated", "suspended"]):
support_request.invalidate()
self.tic()
......@@ -188,6 +183,23 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
# The support request is added to computer owner.
self.assertEquals(support_request.getDestinationDecision(),
host_sub.getDestinationSection())
def test_hosting_subscription_Base_generateSupportRequestForSlapOS(self):
host_sub = self._makeHostingSubscription(self.new_id)
title = "Test Support Request %s" % self.new_id
support_request = host_sub.Base_generateSupportRequestForSlapOS(
title, title, host_sub.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
support_request = self.portal.restrictedTraverse(support_request)
# The support request is added to computer owner.
self.assertEquals(support_request.getDestinationDecision(),
host_sub.getDestinationSection())
def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_open(self):
title = "Test Support Request %s" % self.new_id
......@@ -234,6 +246,29 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(
other_person.getRelativeUrl()))
def test_ERP5Site_isSupportRequestCreationClosed_submitted_state(self):
person = self._makePerson(self.new_id)
url = person.getRelativeUrl()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
def newSupportRequest():
sr = self.portal.support_request_module.newContent(\
title="Test Support Request POIUY",
destination_decision=url)
sr.validate()
sr.suspend()
sr.immediateReindexObject()
# Create five tickets, the limit of ticket creation
newSupportRequest()
newSupportRequest()
newSupportRequest()
newSupportRequest()
newSupportRequest()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
def test_Base_generateSupportRequestForSlapOS_recreate_if_closed(self):
title = "Test Support Request %s" % self.new_id
......@@ -290,6 +325,47 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
self.assertEqual('Visited Base_generateSupportRequestForSlapOS',
result)
def test_SupportRequest_trySendNotificationMessage(self):
title = "Test Support Request %s" % self.new_id
text_content='Test NM content<br/>%s<br/>' % self.new_id
computer = self._makeComputer(self.new_id)
support_request_url = computer.Base_generateSupportRequestForSlapOS(
title, title, computer.getRelativeUrl()
)
support_request = self.portal.restrictedTraverse(support_request_url)
person = computer.getSourceAdministrationValue()
time_before_next = 2
self.tic()
first_event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
source_relative_url=person.getRelativeUrl(),
interval_of_day=time_before_next
)
self.assertNotEqual(first_event, None)
first_event.edit(start_date=(DateTime() - 1.8))
self.tic()
event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
source_relative_url=person.getRelativeUrl(),
interval_of_day=time_before_next
)
self.assertEqual(event, None)
time_before_next = 1
event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
source_relative_url=person.getRelativeUrl(),
interval_of_day=time_before_next
)
self.assertEqual(event.getTitle(), title)
def test_Computer_checkState_empty_cache(self):
computer = self._makeComputer(self.new_id)
......@@ -757,7 +833,7 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by C
computer.workflow_history['edit_workflow'][-1]['comment'])
def _simulateHostingSubscription_checkSofwareInstanceState(self):
script_name = 'HostingSubscription_checkSofwareInstanceState'
script_name = 'HostingSubscription_checkSofwareInstanceAllocationState'
if script_name in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_name)
createZODBPythonScript(self.portal.portal_skins.custom,
......@@ -765,11 +841,11 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by C
'*args, **kw',
'# Script body\n'
"""portal_workflow = context.portal_workflow
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by HostingSubscription_checkSofwareInstanceState') """ )
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by HostingSubscription_checkSofwareInstanceAllocationState') """ )
transaction.commit()
def _dropHostingSubscription_checkSofwareInstanceState(self):
script_name = 'HostingSubscription_checkSofwareInstanceState'
script_name = 'HostingSubscription_checkSofwareInstanceAllocationState'
if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit()
......@@ -788,6 +864,6 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by H
finally:
self._dropHostingSubscription_checkSofwareInstanceState()
self.assertEqual('Visited by HostingSubscription_checkSofwareInstanceState',
self.assertEqual('Visited by HostingSubscription_checkSofwareInstanceAllocationState',
host_sub.workflow_history['edit_workflow'][-1]['comment'])
\ No newline at end of file
37
\ No newline at end of file
44
\ No newline at end of file
......@@ -1691,11 +1691,13 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self.assertTrue(software_release3.getValidationState() == 'released')
software_release1.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1.cfg'
url_string='http://example.org/1.cfg',
effective_date=DateTime()
)
software_release2.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2.cfg'
url_string='http://example.org/2.cfg',
effective_date=DateTime()
)
software_release3.edit(
aggregate_value=software_product.getRelativeUrl(),
......@@ -1722,6 +1724,56 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
""" % (software_release2.getUrlString(), software_release1.getUrlString())
self.assertEqual(expected_xml, got_xml,
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_getSoftwareReleaseListFromSoftwareProduct_effectiveDate(self):
new_id = self.generateNewId()
software_product = self._makeSoftwareProduct(new_id)
# 3 published software releases
software_release1 = self._makeSoftwareRelease(new_id)
software_release2 = self._makeSoftwareRelease(self.generateNewId())
software_release3 = self._makeSoftwareRelease(self.generateNewId())
software_release1.publish()
software_release2.publish()
software_release3.publish()
software_release1.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1.cfg',
effective_date=(DateTime() - 1)
)
# Should not be considered yet!
software_release2.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2.cfg',
effective_date=(DateTime() + 1)
)
software_release3.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/3.cfg',
effective_date=DateTime()
)
self.tic()
response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
software_product.getReference())
# check returned XML
xml_fp = StringIO.StringIO()
xml.dom.ext.PrettyPrint(xml.dom.ext.reader.Sax.FromXml(response),
stream=xml_fp)
xml_fp.seek(0)
got_xml = xml_fp.read()
expected_xml = """\
<?xml version='1.0' encoding='UTF-8'?>
<marshal>
<list id='i2'>
<string>%s</string>
<string>%s</string>
<string>%s</string>
</list>
</marshal>
""" % (software_release3.getUrlString(), software_release1.getUrlString(),
software_release2.getUrlString())
self.assertEqual(expected_xml, got_xml,
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_getSoftwareReleaseListFromSoftwareProduct_emptySoftwareProduct(self):
new_id = self.generateNewId()
......
34
\ No newline at end of file
35
\ No newline at end of file
......@@ -386,9 +386,18 @@ class SlapTool(BaseTool):
raise NotImplementedError('Several Software Product with the same title.')
software_release_list = \
software_product_list[0].getObject().getAggregateRelatedValueList()
def sortkey(software_release):
publication_date = software_release.getEffectiveDate()
if publication_date:
if (publication_date - DateTime()) > 0:
return DateTime('1900/05/02')
return publication_date
return software_release.getCreationDate()
software_release_list = sorted(
software_release_list,
key=lambda software_release: software_release.getCreationDate(),
key=sortkey,
reverse=True,
)
return xml_marshaller.xml_marshaller.dumps(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment