From f54f3e9a0c8fbabe3ccd4e5e27f2085524daa6f0 Mon Sep 17 00:00:00 2001
From: Romain Courteaud <romain@nexedi.com>
Date: Mon, 23 Apr 2012 10:37:01 +0200
Subject: [PATCH] Live test for person_slap_interface_workflow

---
 .../person_module/template_member.xml         | 166 ++++++
 .../testSlapOSCorePersonRequest.py            | 474 ++++++++++++++++++
 .../vifib_slapos_core_test/bt/dependency_list |   1 +
 .../bt5/vifib_slapos_core_test/bt/description |   1 +
 master/bt5/vifib_slapos_core_test/bt/license  |   1 +
 master/bt5/vifib_slapos_core_test/bt/revision |   1 +
 .../bt/template_format_version                |   1 +
 .../bt/template_path_list                     |   1 +
 .../bt/template_test_id_list                  |   1 +
 master/bt5/vifib_slapos_core_test/bt/title    |   1 +
 master/bt5/vifib_slapos_core_test/bt/version  |   1 +
 11 files changed, 649 insertions(+)
 create mode 100644 master/bt5/vifib_slapos_core_test/PathTemplateItem/person_module/template_member.xml
 create mode 100644 master/bt5/vifib_slapos_core_test/TestTemplateItem/testSlapOSCorePersonRequest.py
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/dependency_list
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/description
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/license
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/revision
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/template_format_version
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/template_path_list
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/template_test_id_list
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/title
 create mode 100644 master/bt5/vifib_slapos_core_test/bt/version

diff --git a/master/bt5/vifib_slapos_core_test/PathTemplateItem/person_module/template_member.xml b/master/bt5/vifib_slapos_core_test/PathTemplateItem/person_module/template_member.xml
new file mode 100644
index 000000000..2d3b29861
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/PathTemplateItem/person_module/template_member.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Person" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Access_contents_information_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Auditor</string>
+                <string>Author</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Add_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Author</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Modify_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Author</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_View_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Auditor</string>
+                <string>Author</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>__translation_dict</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_count</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_mt_index</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_tree</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>first_name</string> </key>
+            <value> <string>Member</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>template_member</string> </value>
+        </item>
+        <item>
+            <key> <string>last_name</string> </key>
+            <value> <string>Template</string> </value>
+        </item>
+        <item>
+            <key> <string>password</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Person</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="Length" module="BTrees.Length"/>
+    </pickle>
+    <pickle> <int>0</int> </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+  <record id="5" aka="AAAAAAAAAAU=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>default</string> </key>
+                    <value> <string>{SSHA}f1gAG3A53rfwjkLB/+Ex89MtocZz/4V9K4TZ</string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/vifib_slapos_core_test/TestTemplateItem/testSlapOSCorePersonRequest.py b/master/bt5/vifib_slapos_core_test/TestTemplateItem/testSlapOSCorePersonRequest.py
new file mode 100644
index 000000000..08a5e734e
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/TestTemplateItem/testSlapOSCorePersonRequest.py
@@ -0,0 +1,474 @@
+# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
+from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
+import transaction
+
+class TestSlapOSCorePersonRequest(ERP5TypeTestCase):
+
+  def generateNewId(self):
+    return self.getPortalObject().portal_ids.generateNewId(
+                                     id_group=('slapos_core_test'))
+
+  def afterSetUp(self):
+    portal = self.getPortalObject()
+    new_id = self.generateNewId()
+
+    # Clone person document
+    person_user = portal.person_module.template_member.\
+                                 Base_createCloneDocument(batch_mode=1)
+    person_user.edit(
+      title="live_test_%s" % new_id,
+      reference="live_test_%s" % new_id,
+      default_email_text="live_test_%s@example.org" % new_id,
+    )
+
+    person_user.updateLocalRolesOnSecurityGroups()
+    person_user.validate()
+    for assignment in person_user.contentValues(portal_type="Assignment"):
+      assignment.open()
+    transaction.commit()
+    # XXX Tic is needed to reindex the created open order
+    self.tic()
+
+    # Login as new user
+    self.login(person_user.getReference())
+    new_person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+    self.assertEquals(person_user.getRelativeUrl(), new_person.getRelativeUrl())
+
+  def test_Person_requestSoftwareInstance_requiredParameter(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    self.assertRaises(TypeError, person.requestSoftwareInstance)
+
+    # software_release is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+    # software_title is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+    # software_type is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+    # instance_xml is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+    # instance_xml is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+    # sla_xml is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      shared=shared,
+      state=state,
+    )
+
+    # shared is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      state=state,
+    )
+
+    # state is mandatory
+    self.assertRaises(TypeError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+    )
+
+  def test_Person_requestSoftwareInstance_acceptedState(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    # Only started, stopped, deleted
+    self.assertRaises(ValueError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state="foo",
+    )
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title="started",
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state="started",
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals("started", hosting_subscription.getRootState())
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title="stopped",
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state="stopped",
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals("stopped", hosting_subscription.getRootState())
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title="deleted",
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state="deleted",
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals("deleted", hosting_subscription.getRootState())
+
+  def test_Person_requestSoftwareInstance_returnHostingSubscriptionUrl(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals("Hosting Subscription", 
+                      hosting_subscription.getPortalType())
+
+  def test_Person_requestSoftwareInstance_createHostingSubscription(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    previous_id = self.getPortalObject().portal_ids\
+        .generateNewId(id_group='slap_hosting_subscription_reference', 
+                       id_generator='uid')
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals(software_release, 
+                      hosting_subscription.getRootSoftwareReleaseUrl())
+    self.assertEquals(software_title, hosting_subscription.getTitle())
+    self.assertEquals(software_type, hosting_subscription.getSourceReference())
+    self.assertEquals(instance_xml, hosting_subscription.getTextContent())
+    self.assertEquals(sla_xml, hosting_subscription.getSlaXml())
+    self.assertEquals(shared, hosting_subscription.getRootSlave())
+    self.assertEquals(state, hosting_subscription.getRootState())
+    self.assertEquals("HOSTSUBS-%s" % (previous_id+1),
+                      hosting_subscription.getReference())
+    self.assertEquals("validated", hosting_subscription.getValidationState())
+
+  def test_Person_requestSoftwareInstance_HostingSubscriptionNotReindexed(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+    transaction.commit()
+
+    self.assertRaises(NotImplementedError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+  def test_Person_requestSoftwareInstance_updateHostingSubscription(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    hosting_subscription_reference = hosting_subscription.getReference()
+
+    transaction.commit()
+    self.tic()
+
+    software_release2 = "http://example.org/test.cfg2"
+    software_type2 = "test2"
+    instance_xml2 = "test2"
+    sla_xml2 = "test2"
+    shared2 = False
+    state2 = "stopped"
+
+    person.requestSoftwareInstance(
+      software_release=software_release2,
+      software_title=software_title,
+      software_type=software_type2,
+      instance_xml=instance_xml2,
+      sla_xml=sla_xml2,
+      shared=shared2,
+      state=state2,
+    )
+
+    hosting_subscription2 = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals(hosting_subscription.getRelativeUrl(),
+                      hosting_subscription2.getRelativeUrl())
+    self.assertEquals(hosting_subscription_reference,
+                      hosting_subscription2.getReference())
+
+    self.assertEquals(software_release2, 
+                      hosting_subscription.getRootSoftwareReleaseUrl())
+    self.assertEquals(software_title, hosting_subscription.getTitle())
+    self.assertEquals(software_type2, hosting_subscription.getSourceReference())
+    self.assertEquals(instance_xml2, hosting_subscription.getTextContent())
+    self.assertEquals(sla_xml2, hosting_subscription.getSlaXml())
+    self.assertEquals(shared2, hosting_subscription.getRootSlave())
+    self.assertEquals(state2, hosting_subscription.getRootState())
+    self.assertEquals("validated", hosting_subscription.getValidationState())
+
+  def test_Person_requestSoftwareInstance_duplicatedHostingSubscription(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    hosting_subscription.updateLocalRolesOnSecurityGroups()
+    transaction.commit()
+    hosting_subscription2 = hosting_subscription.Base_createCloneDocument(
+                                                                batch_mode=1)
+    hosting_subscription2.validate()
+
+    transaction.commit()
+    self.tic()
+
+    self.assertRaises(NotImplementedError, person.requestSoftwareInstance,
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+
+  def test_Person_requestSoftwareInstance_HostingSubscriptionNewTitle(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+    state = "started"
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state=state,
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+
+    transaction.commit()
+
+    software_release2 = "http://example.org/test.cfg2"
+    software_title2 = "test2"
+    software_type2 = "test2"
+    instance_xml2 = "test2"
+    sla_xml2 = "test2"
+    shared2 = False
+    state2 = "stopped"
+
+    person.requestSoftwareInstance(
+      software_release=software_release2,
+      software_title=software_title2,
+      software_type=software_type2,
+      instance_xml=instance_xml2,
+      sla_xml=sla_xml2,
+      shared=shared2,
+      state=state2,
+    )
+
+    hosting_subscription2 = person.REQUEST.get('request_hosting_subscription')
+    self.assertNotEquals(hosting_subscription.getRelativeUrl(),
+                      hosting_subscription2.getRelativeUrl())
+    self.assertNotEquals(hosting_subscription.getReference(),
+                      hosting_subscription2.getReference())
+
+    self.assertEquals(software_release2, 
+                      hosting_subscription2.getRootSoftwareReleaseUrl())
+    self.assertEquals(software_title2, hosting_subscription2.getTitle())
+    self.assertEquals(software_type2, hosting_subscription2.getSourceReference())
+    self.assertEquals(instance_xml2, hosting_subscription2.getTextContent())
+    self.assertEquals(sla_xml2, hosting_subscription2.getSlaXml())
+    self.assertEquals(shared2, hosting_subscription2.getRootSlave())
+    self.assertEquals(state2, hosting_subscription2.getRootState())
+    self.assertEquals("validated", hosting_subscription2.getValidationState())
+
+  def test_Person_requestSoftwareInstance_noConflictWithDeletedHostingSubscription(self):
+    person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
+
+    software_release = "http://example.org/test.cfg"
+    software_title = "test"
+    software_type = "test"
+    instance_xml = "test"
+    sla_xml = "test"
+    shared = True
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state="deleted",
+    )
+    hosting_subscription = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals("deleted", hosting_subscription.getRootState())
+    transaction.commit()
+    self.tic()
+
+    person.requestSoftwareInstance(
+      software_release=software_release,
+      software_title=software_title,
+      software_type=software_type,
+      instance_xml=instance_xml,
+      sla_xml=sla_xml,
+      shared=shared,
+      state="started",
+    )
+    hosting_subscription2 = person.REQUEST.get('request_hosting_subscription')
+    self.assertEquals("started", hosting_subscription2.getRootState())
+    self.assertNotEquals(hosting_subscription.getRelativeUrl(), 
+                         hosting_subscription2.getRelativeUrl())
diff --git a/master/bt5/vifib_slapos_core_test/bt/dependency_list b/master/bt5/vifib_slapos_core_test/bt/dependency_list
new file mode 100644
index 000000000..81b7a55ec
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/dependency_list
@@ -0,0 +1 @@
+vifib_slapos_core
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/description b/master/bt5/vifib_slapos_core_test/bt/description
new file mode 100644
index 000000000..a10731bc8
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/description
@@ -0,0 +1 @@
+Test vifib_slapos_core
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/license b/master/bt5/vifib_slapos_core_test/bt/license
new file mode 100644
index 000000000..3a3e12bca
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/license
@@ -0,0 +1 @@
+GPL
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/revision b/master/bt5/vifib_slapos_core_test/bt/revision
new file mode 100644
index 000000000..56a6051ca
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/revision
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/template_format_version b/master/bt5/vifib_slapos_core_test/bt/template_format_version
new file mode 100644
index 000000000..56a6051ca
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/template_path_list b/master/bt5/vifib_slapos_core_test/bt/template_path_list
new file mode 100644
index 000000000..f14c2704e
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/template_path_list
@@ -0,0 +1 @@
+person_module/template_member
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/template_test_id_list b/master/bt5/vifib_slapos_core_test/bt/template_test_id_list
new file mode 100644
index 000000000..627a3a425
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/template_test_id_list
@@ -0,0 +1 @@
+testSlapOSCorePersonRequest
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/title b/master/bt5/vifib_slapos_core_test/bt/title
new file mode 100644
index 000000000..83f77e564
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/title
@@ -0,0 +1 @@
+vifib_slapos_core_test
\ No newline at end of file
diff --git a/master/bt5/vifib_slapos_core_test/bt/version b/master/bt5/vifib_slapos_core_test/bt/version
new file mode 100644
index 000000000..ceab6e11e
--- /dev/null
+++ b/master/bt5/vifib_slapos_core_test/bt/version
@@ -0,0 +1 @@
+0.1
\ No newline at end of file
-- 
2.30.9