This commit is contained in:
Anna Sudnitsina 2018-09-10 22:55:13 +03:00
parent b13048293c
commit 839c736feb
19 changed files with 2136 additions and 0 deletions

17
Dockerfile Normal file
View File

@ -0,0 +1,17 @@
FROM python:alpine
MAINTAINER Anna Sudnitsyna
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install selenium
COPY . .
#EXPOSE 8000
#ENTRYPOINT python3 manage.py runserver 0.0.0.0:8000
ENTRYPOINT ls && python manage.py test tests.selenium.dashboard_test

0
__init__.py Normal file
View File

0
api/__init__.py Normal file
View File

1
api/test_inventory.json Normal file

File diff suppressed because one or more lines are too long

422
api/tests_api.py Normal file
View File

@ -0,0 +1,422 @@
from django.test import TestCase, TransactionTestCase
from django.urls import reverse
from authtoken.models import *
from api.models import *
from django.contrib.auth.models import User
import json
from django.db import transaction
from api.ini_serializer import ini
class NotFoundTest(TestCase):
def test_not_api(self):
url = '/n/a'
response = self.client.get(url)
self.assertEquals(response.status_code, 404)
class TokenTestBase(TestCase):
def setUp(self):
self.u = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
self.inventory = Inventory.objects.create(inventory='inv_in_scope', user=self.u)
self.token = InventoryToken.objects.create(user=self.u, description='test_scoped_token')
self.token.inventory.add(self.inventory)
self.admin_token = Token.objects.create(user=self.u)
class InventoryTest(TokenTestBase):
inv_name = 'test_inventory'
def test_create_admin_token(self):
url = reverse('inventory_details', args=[self.inv_name])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"inv"}')
def test_create_scoped_token(self):
url = reverse('inventory_details', args=[self.inv_name])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.status_code, 404)
self.assertJSONEqual(response.content.decode(), '{"detail":"Not found."}')
def test_get_admin_token(self):
url = reverse('inventory_details', args=[self.inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key} )
self.assertJSONEqual(
response.content.decode(),
'{"all":{"hosts":[],"children":[],"vars":{"inventory_name":"inv_in_scope"}}}')
def test_get_scoped_token(self):
# inv in scope: return inv
url = reverse('inventory_details', args=[self.inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(
response.content.decode(),
'{"all":{"hosts":[],"children":[],"vars":{"inventory_name":"inv_in_scope"}}}')
# inv doesnt exist: return "doesnt exist"
url = reverse('inventory_details', args=[self.inv_name])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(response.content.decode(), '{"detail":"Not found."}')
# inv not in scope: return {"detail":"Acess denied"}
Inventory.objects.create(inventory='inv_not_in_scope', user=self.u)
url = reverse('inventory_details', args=['inv_not_in_scope'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(response.content.decode(), '{"detail":"Acess denied"}')
def test_delete_admin_token(self):
url = reverse('inventory_details', args=[self.inventory])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"inventory"}')
# inv doesnt exist: return "doesnt exist"
url = reverse('inventory_details', args=[self.inv_name])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEquals(response.content.decode(), '{"detail":"Not found."}')
def test_delete_scoped_token(self):
# inv not in scope doesnt exist: return {"detail":"Not found."}
url = reverse('inventory_details', args=[self.inv_name])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(response.content.decode(), '{"detail":"Not found."}')
# inv not in scope: return {"detail":"Not found."}
Inventory.objects.create(inventory = self.inv_name, user=self.u)
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
# get list of inv
url = reverse('inventory_list')
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertListEqual(json.loads(response.content.decode()), ["inv_in_scope", "test_inventory"])
# inv in scope: return {"status":"DELETE","details":"inventory"}
url = reverse('inventory_details', args=[self.inventory])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"inventory"}')
# get list of inv
url = reverse('inventory_list')
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEquals(response.content.decode(), '["test_inventory"]')
def test_limit(self):
def create_inv(name):
url = reverse('inventory_details', args=[name])
return self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
for i in range(4):
r = create_inv('inv_%s' % i)
self.assertEquals(r.content.decode(), '"inventories limit exceeded"')
def test_already_exist(self):
name = 'some_name'
url = reverse('inventory_details', args=[name])
self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
r = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEquals(r.content.decode(), '"already exists"')
class MachineTest(TokenTestBase):
def test_create_delete_scoped_token(self):
"""
create machine - True
get list of machines - True
"""
url = reverse('machine', args=['test_machine'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
url = reverse('machine')
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEqual(response.content.decode(), '["test_machine"]')
url = reverse('machine', args=['test_machine'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
url = reverse('machine')
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEqual(response.content.decode(), '[]')
class GroupTest(TokenTestBase):
def setUp(self):
super(GroupTest, self).setUp()
Group.objects.create(inventory=self.inventory, group='test_group_to_delete')
def test_create_admin_token(self):
url = reverse('group_details', args=[self.inventory, 'test_group'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
url = reverse('group_list', args=[self.inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertListEqual(json.loads(response.content.decode()), ["test_group", "test_group_to_delete"])
def test_create_scoped_token(self):
# valid token
url = reverse('group_details', args=[self.inventory, 'test_group'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
url = reverse('group_list', args=[self.inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertListEqual(json.loads(response.content.decode()), ["test_group", "test_group_to_delete"])
# invalid token
token = InventoryToken.objects.create(user=self.u, description='test_scoped_token1')
url = reverse('group_details', args=[self.inventory, 'test_group1'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': token.token})
self.assertJSONEqual(response.content.decode(), '{"detail":"Acess denied"}')
def test_delete_admin_token(self):
url = reverse('group_details', args=[self.inventory, 'test_group_to_delete'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"DELETE","details":"group"}')
url = reverse('group_list', args=[self.inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEquals(response.content.decode(), '[]')
def test_delete_scoped_token(self):
# invalid token
token = InventoryToken.objects.create(user=self.u, description='test_scoped_token1')
url = reverse('group_details', args=[self.inventory, 'test_group_to_delete'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': token.token})
self.assertJSONEqual(response.content.decode(), '{"detail":"Acess denied"}')
url = reverse('group_details', args=[self.inventory, 'test_group_to_delete'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"DELETE","details":"group"}')
url = reverse('group_list', args=[self.inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '[]')
def test_delete_doesnt_exist(self):
url = reverse('group_details', args=[self.inventory, 'not_exist'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"detail":"Not found."}')
class VariableTest(TokenTestBase):
def setUp(self):
super(VariableTest, self).setUp()
self.group = Group.objects.create(inventory=self.inventory, group='test_group')
def test_create_scoped_token(self):
url = reverse('vars_details', args=[self.inventory, self.group, 'test_var'])
response = self.client.put(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"ADD","details":"var"}')
"""check var"""
url = reverse('vars_list', args=[self.inventory, self.group])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '["test_var"]')
url = reverse('vars_details', args=[self.inventory, self.group, 'test_var'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '"test_val"')
"""delete vars"""
url = reverse('vars_details', args=[self.inventory, self.group, 'test_var'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"DELETE","details":"var"}')
url = reverse('vars_list', args=[self.inventory, self.group])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '[]')
class HostTest(TokenTestBase):
def setUp(self):
super(HostTest, self).setUp()
self.group = Group.objects.create(inventory=self.inventory, group='test_group')
self.machine = Machine.objects.create(machine='mach', user=self.u)
mach = Machine.objects.create(machine='test_duplicate_machine', user=self.u)
Host.objects.create(group=self.group, host=mach)
def test_create_scoped_token(self):
"""create host"""
url = reverse('host', args=[self.inventory, self.group, self.machine])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"ADD","details":"host"}')
"""check hosts"""
url = reverse('host', args=[self.inventory, self.group])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertListEqual(json.loads(response.content.decode()), ["mach","test_duplicate_machine"])
"""delete host"""
url = reverse('host', args=[self.inventory, self.group, self.machine])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"DELETE","details":"host"}')
"""check hosts"""
url = reverse('host', args=[self.inventory, self.group])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '["test_duplicate_machine"]')
def test_duplicates_creation(self):
url = reverse('host', args=[self.inventory, self.group, 'test_duplicate_machine'])
with transaction.atomic():
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '"already exists"')
url = reverse('host', args=[self.inventory, 'test_group'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '["test_duplicate_machine"]')
# Djangos TestCase class wraps each test in a transaction for performance reasons.
class ChildTest(TokenTestBase):
def setUp(self):
super(ChildTest, self).setUp()
self.parent_group = Group.objects.create(inventory=self.inventory, group='parent')
self.child_group = Group.objects.create(inventory=self.inventory, group='child')
self.duplicate = Group.objects.create(inventory=self.inventory, group='duplicate_child')
self.duplicate_child = Child.objects.create(group=self.parent_group, child=self.duplicate)
def test_general_scoped_token(self):
"""create child"""
url = reverse('child', args=[self.inventory, self.parent_group, self.child_group])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"ADD","details":"child"}')
"""check child"""
url = reverse('child', args=[self.inventory, self.parent_group])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertListEqual(json.loads(response.content), ["child", "duplicate_child"])
"""delete child"""
url = reverse('child', args=[self.inventory, self.parent_group, self.child_group])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '{"status":"DELETE","details":"child"}')
"""check child"""
url = reverse('child', args=[self.inventory, self.parent_group])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '["duplicate_child"]')
"""assign group to itself as a child"""
url = reverse('child', args=[self.inventory, self.parent_group, self.parent_group])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEquals(response.content.decode(), '"group can\'t be a child of itself"')
class GeneralTest(TestCase):
def setUp(self):
u = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
Token.objects.create(user=u)
def test_scoped_token(self):
"""create new inv, check availability with scoped token"""
inv_name = "django_test_inv"
u = User.objects.get(username='john')
inventory = Inventory.objects.create(inventory=inv_name, user = u)
token = InventoryToken.objects.create(user=u, description='test_token')
token.inventory.add(inventory)
self.assertTrue(token)
self.assertListEqual(list(token.inventory.all()), list(Inventory.objects.all()))
new_group = Group.objects.create(inventory=inventory, group='test_group')
"""check group list availability with scoped token"""
url = reverse('group_list', args=[inventory])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': token.token})
self.assertEquals(response.status_code, 200)
"""create new inv, check availability with token not containing this inv in scope"""
inventory2 = Inventory.objects.create(inventory = 'inv_name2', user = u)
url = reverse('group_list', args=[inventory2])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': token.token})
self.assertEqual(response.content.decode(), '{"detail":"Acess denied"}')
"""check availability with non-existent token"""
token = InventoryToken(token='123')
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': token.token})
self.assertEqual(response.content.decode(), '{"detail":"No such user"}')
class Upload(TokenTestBase):
inventory_data = """{"group2": {},
"group1": {
"vars": {"234": "234"},
"hosts": ["1.com", "two.com"],
"children": ["group2"]
},
"group3": {},
"_meta" : {
"hostvars" : {
"1.com" : {
"sensu_address": "10.128.13.118",
"sensu_bind": "127.0.0.1"
}
}
}
}"""
def test_inventory_upload(self):
dict1 = json.loads(self.inventory_data)
inv_name = 'uploaded_inventory'
# inv_name='groupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroupgroup'
url = reverse('inventory_details', args=[inv_name])
# no token
response = self.client.put(url, data=self.inventory_data)
self.assertEqual(
response.content.decode(),
'{"detail":"Authentication credentials were not provided."}'
)
# invalid token
token = InventoryToken(token='123')
response = self.client.put(url, data=self.inventory_data, **{'HTTP_X_AUTH_TOKEN': token.token})
self.assertEqual(response.content.decode(), '{"detail":"No such user"}')
# valid admin Token
token = Token.objects.get(user=self.u)
response = self.client.put(url, data=self.inventory_data, **{'HTTP_X_AUTH_TOKEN': token.key})
self.assertEqual(response.content.decode(), 'done')
# check groups uploaded
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': token.key})
dict2 = json.loads(response.content.decode())
l1 = list(dict1.keys()) + ['all', '_meta']
self.assertSetEqual(set(l1), set(dict2.keys()))
# additional test for dashboard
url = reverse('upload')
form_data = {"inv_name": 'test_upl', "uploaded": self.inventory_data}
self.client.force_login(self.u)
response = self.client.post(url, form_data)
self.assertEqual(response.content.decode(), 'done')
# check groups uploaded
url = reverse('inventory_details', args=['test_upl'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': token.key})
dict2 = json.loads(response.content.decode())
l1 = list(dict1.keys()) + ['all', '_meta']
self.assertSetEqual(set(l1), set(dict2.keys()))
def test_upload_ini(self):
# valid admin Token
inv_name = 'uploaded_inventory'
token = Token.objects.get(user=self.u)
url = reverse('inventory_details', args=[inv_name])
response = self.client.put(url, data=ini, **{'HTTP_X_AUTH_TOKEN': token.key})
self.assertEqual(response.content.decode(), 'done') # TODO: check if uploaded correctly
# class ScopedToken(TransactionTestCase):
# def setUp(self):
# self.u = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
# self.inventory = Inventory.objects.create(inventory = 'inv_name', user = self.u)
# self.token = InventoryToken.objects.create(user=self.u, description='test_scoped_token')
# self.token.inventory.add(self.inventory)
# self.machine = Machine.objects.create(user = self.u, machine='test_duplicate_machine')
# self.group = Group.objects.create(inventory=self.inventory, group='test_duplicate_group')
# self.host = Host.objects.create(group=self.group, host=self.machine)
class CharsTest(TokenTestBase):
def test_group(self):
my_name = "group.group"
url = '/api/inventory/' + str(self.inventory) + '/groups/' + my_name
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEqual(response.content.decode(), '{"detail":"bad request"}')
url = '/api/inventory/' + str(self.inventory) + '/groups/' + my_name + '/'
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEqual(response.content.decode(), '{"detail":"bad request"}')
url = '/api/inventory/' + str(self.inventory) + '/groups/' + my_name
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.admin_token.key})
self.assertEqual(response.content.decode(), '{"detail":"Not found."}')
def test_vars(self):
group = Group.objects.create(inventory=self.inventory, group="test_group")
my_var = 'test%var'
url = '/api/inventory/' + str(self.inventory) + '/groups/' + str(group) + '/vars/' + my_var + '/'
response = self.client.put(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEqual(response.content.decode(), '{"detail":"bad request"}')
"""check var"""
url = '/api/inventory/' + str(self.inventory) + '/groups/' + str(group) + '/vars'
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(response.content.decode(), '[]')
url = '/api/inventory/' + str(self.inventory) + '/groups/' + str(group) + '/vars/' + my_var + '/'
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertJSONEqual(response.content.decode(), '{"detail":"Not found."}')
def test_host_vars(self):
my_var = 'test;var'
mach = Machine.objects.create(user=self.u, machine="test_mach")
url = '/api/inventory/' + str(self.inventory) + '/host/' + str(mach) + '/host_vars/' + my_var
response = self.client.put(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEqual(response.content.decode(), '{"detail":"bad request"}')
self.assertEqual(response.status_code, 400)
url = '/api/inventory/' + str(self.inventory) + '/host/' + str(mach) + '/host_vars/' + my_var + '/'
response = self.client.put(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEqual(response.content.decode(), '{"detail":"bad request"}')
url = '/api/inventory/' + str(self.inventory) + '/host/' + str(mach) + '/host_vars/' + 'normal_var' + '/'
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': self.token.token})
self.assertEqual(response.content.decode(), '{"detail":"Not found."}')

63
api/tests_ini.py Normal file
View File

@ -0,0 +1,63 @@
from unittest import TestCase
from api import ini_serializer
EXPECTED_RESULT={
"_meta": {
"hostvars": {
"host1": {
"123": "45632",
"567": "890",
"port": "45632"
},
"host2": {
"a": "b"
},
"host4": {
"ansible_ssh_port": "2233"
}
}
},
"atlanta": {
"hosts": [
"host1",
"host2"
]
},
"raleigh": {
"hosts": [
"host1",
"host4",
"host3"
]
},
"southeast": {
"children": [
"atlanta",
"raleigh"
],
"vars": {
"some_server": "foo.southeast.example.com",
"halon_system_timeout": "30",
"self_destruct_countdown": "60",
"escape_pods": "2"
}
},
"usa": {
"children": [
"southeast",
"northeast"
]
}
}
class INITest(TestCase):
def test_conversion(self):
result = ini_serializer.serializer(ini_serializer.ini)
self.assertDictEqual(result, EXPECTED_RESULT)
def test_invalid_data(self):
data = "123"
with self.assertRaises(ValueError):
ini_serializer.serializer(data)

67
api/tests_models.py Normal file
View File

@ -0,0 +1,67 @@
from django.contrib.auth.models import User
from django.test import TestCase
from api import models
class MachineTest(TestCase):
def test_init(self):
obj = models.Machine(machine="my_machine")
self.assertEqual(str(obj), "my_machine")
class InventoryTest(TestCase):
def test_init(self):
obj = models.Inventory(inventory="my_inv")
self.assertEqual(str(obj), "my_inv")
class GroupTest(TestCase):
def test_init(self):
obj = models.Group(group="my_group")
self.assertEqual(str(obj), "my_group")
class VariableTest(TestCase):
def test_init(self):
obj = models.Variable(variable="my_var", value="my_val")
self.assertEqual(str(obj), "my_var")
class HostTest(TestCase):
def test_init(self):
mach = models.Machine(machine="my_machine")
obj = models.Host(host=mach)
self.assertEqual(str(obj), "my_machine")
class ChildTest(TestCase):
def test_init(self):
parent = models.Group(group="p_group")
child = models.Group(group="c_group")
obj = models.Child(group=parent, child=child)
self.assertEqual(str(obj), "c_group")
class HostVariableTest(TestCase):
def test_init(self):
obj = models.HostVariable(variable="my_var", value="my_val")
self.assertEqual(str(obj), "my_var")
class InventorySaveTest(TestCase):
def setUp(self):
self.user = User(username="tester")
self.user.save()
def test_inventory(self):
inv = models.Inventory(inventory="saved_inventory", user=self.user)
inv.save()
self.assertTrue(models.Inventory.objects.filter(inventory="saved_inventory", user=self.user).exists())
def test_inv_limit_error(self):
with self.assertRaises(models.LimitError):
for i in range(4):
inv = models.Inventory(inventory=str(i), user=self.user)
inv.save()

311
api/tests_views.py Normal file
View File

@ -0,0 +1,311 @@
from django.test import TestCase, TransactionTestCase
from django.urls import reverse
from authtoken.models import *
from api.models import *
from django.contrib.auth.models import User
import json
from django.db import transaction
from api.ini_serializer import ini
import time
TOKEN = "790cb216be621e8b2e7c064e21f9f4fb020808071176655f9df1ac713f643d21"
INVENTORY = '{"test_gr": {"vars": {"test_var": "test"}, "hosts": ["test.test"], "children": ["child_gr"]}, "child_gr": {"vars": {}, "hosts": [], "children": []}, "all": {"vars": {"inventory_name": "test_inv"}, "hosts": [], "children": []}}'
class NotFoundTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_not_api(self):
url = "/n/a"
response = self.client.get(url)
self.assertEquals(response.status_code, 404)
def test_api_get(self):
url = "/api/n/a"
response = self.client.get(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 404)
self.assertEqual(response.content.decode(), '{"detail":"Not found."}')
def test_api_put(self):
url = "/api/n/a"
response = self.client.put(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 400)
self.assertEqual(response.content.decode(), '{"detail":"bad request"}')
class InventoryTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_list(self):
url = reverse("inventory_list")
print(url)
response = self.client.get(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.content.decode(), '["test_inv"]')
def test_json(self):
url = reverse("inventory_details", args=["test_inv"])
response = self.client.get(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertJSONEqual(response.content.decode(), INVENTORY)
def test_create(self):
url = reverse("inventory_details", args=["created_inv"])
response = self.client.put(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"inv"}')
self.assertTrue(Inventory.objects.filter(inventory="created_inv").exists())
def test_create_error(self):
url = reverse("inventory_details", args=["test_inv"])
response = self.client.put(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"already exists"') # TODO check if " are needed
def test_delete(self):
url = reverse("inventory_details", args=["test_inv"])
response = self.client.delete(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"inventory"}') # TODO change datails for different actions, inv or inventory for all
self.assertFalse(Inventory.objects.filter(inventory="test_inv").exists())
def test_upload(self):
url = reverse('inventory_details', args=["upl_inv1"])
self.client.delete(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
response = self.client.put(url, data=INVENTORY, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEqual(response.content.decode(), 'done')
def test_upload_error(self):
url = reverse('inventory_details', args=["upl_inv1"])
response = self.client.put(url, data='string', **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), 'invalid data')
data = '{"test_gr": {"hosts": "string"}}'
response = self.client.put(url, data=data, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), 'hosts should be list')
class GroupTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
# url = reverse("group_list", args=["test_inv"])
def test_list(self):
url = reverse("group_list", args=["test_inv"])
response = self.client.get(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.content.decode(), '["child_gr", "test_gr"]')
def test_create(self):
url = reverse("group_details", args=["test_inv", "created_group"])
response = self.client.put(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"group"}')
self.assertTrue(Group.objects.filter(group="created_group").exists())
def test_create_error(self):
url = reverse("group_details", args=["test_inv", "test_gr"])
response = self.client.put(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"already exists"')
def test_delete(self):
url = reverse("group_details", args=["test_inv", "test_gr"])
response = self.client.delete(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"group"}')
self.assertFalse(Group.objects.filter(group="test_gr").exists())
def test_delete_error(self):
url = reverse("group_details", args=["test_inv", "not_exist"])
response = self.client.delete(url, **{"HTTP_X_AUTH_TOKEN": TOKEN})
self.assertEquals(response.status_code, 404)
self.assertEqual(response.content.decode(), '{"detail":"Not found."}')
class MachineTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_list(self):
url = reverse('machine')
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEqual(response.content.decode(), '["test.test"]')
def test_create(self):
url = reverse('machine', args=['create.test'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"machine"}')
self.assertTrue(Machine.objects.filter(machine="create.test").exists())
def test_create_error(self):
url = reverse('machine', args=['test.test'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"already exists"')
def test_delete(self):
url = reverse('machine', args=['test.test'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"machine"}')
self.assertFalse(Machine.objects.filter(machine="create.test").exists())
def test_delete_error(self):
url = reverse('machine', args=['not_exist.test'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 404)
self.assertEqual(response.content.decode(), '{"detail":"Not found."}')
class HostTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_list(self):
url = reverse('host', args=['test_inv', 'test_gr'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '["test.test"]')
def test_create(self):
url = reverse('host', args=['test_inv', 'child_gr', 'test.test'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"host"}')
self.assertTrue(Host.objects.filter(host=Machine.objects.get(machine="test.test"),
group=Group.objects.filter(group="child_gr").exists()))
def test_create_error(self):
url = reverse('host', args=['test_inv', 'child_gr', 'not_exist.test'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 404)
self.assertJSONEqual(response.content.decode(), '{"detail":"Not found."}')
url = reverse('host', args=['test_inv', 'test_gr', 'test.test'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"already exists"')
def test_delete(self):
url = reverse('host', args=['test_inv', 'test_gr', 'test.test'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"host"}')
self.assertFalse(Host.objects.filter(host=Machine.objects.get(machine="test.test"),
group=Group.objects.filter(group="child_gr").exists()))
class ChildTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_list(self):
url = reverse('child', args=['test_inv', 'test_gr'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '["child_gr"]')
def test_create(self):
url = reverse('child', args=['test_inv', 'child_gr', 'test_gr'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"child"}')
self.assertTrue(Host.objects.filter(host=Machine.objects.get(machine="test.test"),
group=Group.objects.filter(group="child_gr").exists()))
def test_create_404(self):
url = reverse('child', args=['test_inv', 'child_gr', 'some_gr'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 404)
self.assertJSONEqual(response.content.decode(), '{"detail":"Not found."}')
def test_create_error(self):
url = reverse('child', args=['test_inv', 'child_gr', 'child_gr'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEquals(response.content.decode(), '"group can\'t be a child of itself"')
def test_delete(self):
url = reverse('child', args=['test_inv', 'test_gr', 'child_gr'])
response = self.client.delete(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"DELETE","details":"child"}')
self.assertFalse(Child.objects.filter(group=Group.objects.get(group="test_gr"),
child=Group.objects.get(group="child_gr")).exists())
class VariableTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_crud(self):
# put
url = reverse('vars_details', args=['test_inv', 'child_gr', 'test_var'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"var"}')
# put - error data
url = reverse('vars_details', args=['test_inv', 'test_gr', 'test_var'])
response = self.client.put(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"already exists"')
# get list
url = reverse('vars_list', args=['test_inv', 'test_gr'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '["test_var"]')
# post
url = reverse('vars_details', args=['test_inv', 'test_gr', 'test_var'])
response = self.client.post(url, data="changed_val", content_type="application/json",
**{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertJSONEqual(response.content.decode(), '{"status":"UPDATE","details":"var"}')
# get value
url = reverse('vars_details', args=['test_inv', 'test_gr', 'test_var'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"changed_val"')
# delete
url = reverse('vars_details', args=['test_inv', 'test_gr', 'test_var'])
response = self.client.delete(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '{"status":"DELETE","details":"var"}')
class HostVariableTest(TestCase):
fixtures = ["tests/api/test_inventory.json"]
def test_crud(self):
# put
url = reverse('hostvars_details', args=['test_inv', 'test.test', 'test_hostvar'])
response = self.client.put(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertJSONEqual(response.content.decode(), '{"status":"ADD","details":"hostvar"}')
# put - error data
url = reverse('hostvars_details', args=['test_inv', 'test.test', 'test_hostvar'])
response = self.client.put(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"already exists"')
# post
url = reverse('hostvars_details', args=['test_inv', 'test.test', 'test_hostvar'])
response = self.client.post(url, data="changed_val", content_type="application/json",
**{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertJSONEqual(response.content.decode(), '{"status":"UPDATE","details":"hostvar"}')
# get list
url = reverse('hostvars_list', args=['test_inv', 'test.test'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '["test_hostvar"]')
# get value
url = reverse('hostvars_details', args=['test_inv', 'test.test', 'test_hostvar'])
response = self.client.get(url, **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '"changed_val"')
# delete
url = reverse('hostvars_details', args=['test_inv', 'test.test', 'test_hostvar'])
response = self.client.delete(url, data='test_val', **{'HTTP_X_AUTH_TOKEN': TOKEN})
self.assertEquals(response.status_code, 200)
self.assertEqual(response.content.decode(), '{"status":"DELETE","details":"hostvar"}')

13
docker-compose.yml Normal file
View File

@ -0,0 +1,13 @@
version: '2'
services:
web:
build:
context: ../
dockerfile: tests/Dockerfile
expose:
- "8000"
depends_on:
- selenium
selenium:
image: selenium/standalone-chrome

View File

@ -0,0 +1,27 @@
{
"id": "d4e23e5f-8d9d-4dd4-afdf-f15954e40875",
"name": "Inventory API",
"values": [
{
"key": "url",
"value": "http://127.0.0.1:8000",
"enabled": true,
"type": "text"
},
{
"key": "token",
"value": "efefc75ba5efdebb9b5090662d35ffbc952b11b5b4bd48625fde5c9794af72c2",
"enabled": true,
"type": "text"
},
{
"key": "inv",
"value": "my_inv",
"enabled": true,
"type": "text"
}
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2018-06-26T13:37:31.232Z",
"_postman_exported_using": "Postman/6.1.3"
}

View File

@ -0,0 +1,878 @@
{
"info": {
"_postman_id": "3bf6d521-6003-49a8-902c-f8f7c190610d",
"name": "inventory",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "delete inventory Copy",
"event": [
{
"listen": "test",
"script": {
"id": "4fecac5d-bd31-49df-bdab-d56b1a4cfb65",
"type": "text/javascript",
"exec": [
"// postman.clearEnvironmentVariable(\"inv\");",
"",
"tests[\"status code is 200\"] == responseCode.code === 200;",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"status\"] == \"DELETE\"; jsonData[\"details\"] == \"inventory\";"
]
}
}
],
"request": {
"method": "DELETE",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/{{inv}}",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"{{inv}}"
]
}
},
"response": []
},
{
"name": "create inventory",
"event": [
{
"listen": "test",
"script": {
"id": "661c9fbf-3f52-4256-9220-8d32cbfda581",
"type": "text/javascript",
"exec": [
"//postman.clearEnvironmentVariable(\"inv\");",
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"tests[\"status code is 200\"] == responseCode.code === 200;"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{url}}/api/inventory/{{inv}}",
"host": [
"{{url}}"
],
"path": [
"api",
"inventory",
"{{inv}}"
]
}
},
"response": []
},
{
"name": "inventory",
"event": [
{
"listen": "test",
"script": {
"id": "86d4831a-6fca-40c1-ab71-e88615c0e4fe",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"var jsonData = JSON.parse(responseBody);",
"",
"tests['json'] = responseBody.indexOf(postman.getEnvironmentVariable(\"inv\")) !== -1;",
"tests[\"content type\"] = postman.getResponseHeader('Content-Type') === 'application/json';",
"",
"//postman.setEnvironmentVariable(\"inv\", jsonData);",
"tests[\"Body is object\"] = typeof jsonData == \"object\";",
"",
""
]
}
}
],
"request": {
"method": "GET",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{url}}/api/inventories",
"host": [
"{{url}}"
],
"path": [
"api",
"inventories"
]
}
},
"response": []
},
{
"name": "group create",
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/{{inv}}/groups/first_group",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"{{inv}}",
"groups",
"first_group"
]
}
},
"response": []
},
{
"name": "group create child",
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/my_child",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"my_child"
]
}
},
"response": []
},
{
"name": "groups",
"request": {
"method": "GET",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{url}}/api/inventory/my_inv/groups/",
"host": [
"{{url}}"
],
"path": [
"api",
"inventory",
"my_inv",
"groups",
""
]
}
},
"response": []
},
{
"name": "vars create",
"event": [
{
"listen": "test",
"script": {
"id": "da5ac7be-0908-4d8f-9f44-5ccc79342c27",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"tests[\"response\"] = responseBody.has(\"details\");",
"tests[\"response\"] = responseBody.has(\"status\");",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"details\"] == \"var\";",
"tests['json'] = jsonData[\"status\"] == \"ADD\";"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/vars/my_var",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"vars",
"my_var"
]
}
},
"response": []
},
{
"name": "vars",
"request": {
"method": "GET",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/vars",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"vars"
]
}
},
"response": []
},
{
"name": "vars del",
"event": [
{
"listen": "test",
"script": {
"id": "f6d31c41-d654-44fa-93fc-3162c495af87",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"tests[\"response\"] = responseBody.has(\"details\");",
"tests[\"response\"] = responseBody.has(\"status\");",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"details\"] == \"var\";",
"tests['json'] = jsonData[\"status\"] == \"DELETE\";"
]
}
}
],
"request": {
"method": "DELETE",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/vars/my_var",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"vars",
"my_var"
]
}
},
"response": []
},
{
"name": "children create",
"event": [
{
"listen": "test",
"script": {
"id": "78e0f95f-2727-41d7-a919-be694b4716c4",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"tests[\"response\"] = responseBody.has(\"details\");",
"tests[\"response\"] = responseBody.has(\"status\");",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"details\"] == \"child\";",
"tests['json'] = jsonData[\"status\"] == \"ADD\";"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/children/my_child",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"children",
"my_child"
]
}
},
"response": []
},
{
"name": "children",
"event": [
{
"listen": "test",
"script": {
"id": "d3923c09-9f3d-44c6-ab76-5c799bad421f",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"request": {
"method": "GET",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/children",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"children"
]
}
},
"response": []
},
{
"name": "hosts create",
"event": [
{
"listen": "test",
"script": {
"id": "040fd106-e290-4c49-86ee-fb1dd3c24dfd",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"tests[\"response\"] = responseBody.has(\"detail\");",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"detail\"] == \"Not found.\";"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/hosts/my_host",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"hosts",
"my_host"
]
}
},
"response": []
},
{
"name": "machine create",
"event": [
{
"listen": "test",
"script": {
"id": "6c3f2287-161c-42b3-9280-c10cfd2aa9af",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"status\"] == \"ADD\"; jsonData[\"details\"] == \"machine\"; "
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/machines/my_machine",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"machines",
"my_machine"
]
}
},
"response": []
},
{
"name": "hosts create successfully",
"event": [
{
"listen": "test",
"script": {
"id": "c73220fb-c363-4672-bb25-2d171c4f204f",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"status\"] == \"ADD\"; jsonData[\"details\"] == \"host\"; "
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/hosts/my_machine",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"hosts",
"my_machine"
]
}
},
"response": []
},
{
"name": "hosts",
"request": {
"method": "GET",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/my_inv/groups/first_group/hosts",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"my_inv",
"groups",
"first_group",
"hosts"
]
}
},
"response": []
},
{
"name": "machine delete",
"event": [
{
"listen": "test",
"script": {
"id": "1c568b7f-6f0b-472f-9a4b-e33404b7db3a",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"",
"var jsonData = JSON.parse(responseBody);",
"tests['response'] = jsonData[\"status\"] == \"DELETE\"; jsonData[\"details\"] == \"machine\"; ",
"",
""
]
}
}
],
"request": {
"method": "DELETE",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{url}}/api/machines/my_machine",
"host": [
"{{url}}"
],
"path": [
"api",
"machines",
"my_machine"
]
}
},
"response": []
},
{
"name": "get inventory json",
"event": [
{
"listen": "test",
"script": {
"id": "80ef89ad-c979-4fdf-941a-ae9bce482c44",
"type": "text/javascript",
"exec": [
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"tests[\"status code is 200\"] == responseCode.code === 200;",
"var jsonData = JSON.parse(responseBody);",
"tests[\"Response contains 'all'\"] = responseBody.has(\"all\");"
]
}
}
],
"request": {
"method": "GET",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{url}}/api/inventory/my_inv",
"host": [
"{{url}}"
],
"path": [
"api",
"inventory",
"my_inv"
]
}
},
"response": []
},
{
"name": "delete inventory",
"event": [
{
"listen": "test",
"script": {
"id": "4fecac5d-bd31-49df-bdab-d56b1a4cfb65",
"type": "text/javascript",
"exec": [
"// postman.clearEnvironmentVariable(\"inv\");",
"",
"tests[\"status code is 200\"] == responseCode.code === 200;",
"var jsonData = JSON.parse(responseBody);",
"tests['json'] = jsonData[\"status\"] == \"DELETE\"; jsonData[\"details\"] == \"inventory\";"
]
}
}
],
"request": {
"method": "DELETE",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://127.0.0.1:8000/api/inventory/{{inv}}",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"api",
"inventory",
"{{inv}}"
]
}
},
"response": []
},
{
"name": "upload inventory",
"event": [
{
"listen": "test",
"script": {
"id": "26ce0c85-61e2-42f5-a0ad-b18420c0a589",
"type": "text/javascript",
"exec": [
"//postman.clearEnvironmentVariable(\"inv\");",
"tests[\"Response time is less than 200ms\"] = responseTime < 200;",
"tests[\"status code is 200\"] == responseCode.code === 200;",
"",
"",
"// var jsonData = JSON.parse(responseBody);",
"tests['json'] =responseBody == \"done\";"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "X-Auth-Token",
"value": "{{token}}"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"group2\": {},\r\n \"group1\": {\r\n \"vars\": {\"234\": \"{\\\"myvar\\\": \\\"ttttt\\\", \\\"o\\\": [1,2,3], \\\"j\\\": {}}\"},\r\n \"hosts\": [\"1.com\", \"two.com\", 3],\r\n \"children\": [\"group2\"]\r\n },\r\n \"group3\": {},\r\n \"_meta\" : {\r\n \"hostvars\" : {\r\n \"1.com\" : {\r\n \"sensu_address\": \"10.128.13.118\",\r\n \"sensu_bind\": {\"127.0.0.1\": \"ololo\"}\r\n }\r\n }\r\n }\r\n }"
},
"url": {
"raw": "{{url}}/api/inventory/{{inv}}",
"host": [
"{{url}}"
],
"path": [
"api",
"inventory",
"{{inv}}"
]
}
},
"response": []
}
]
}

View File

@ -0,0 +1,30 @@
import random
import string
import json
def inventory_generator():
data = {"_meta": {"hostvars": {}}}
def rnd_string(): return ''.join(random.choices(
string.ascii_letters + string.digits, k=10))
hosts = [rnd_string() for i in range(500)]
for i in range(200):
data[rnd_string()] = {"vars": {rnd_string(): rnd_string() for i in range(10)},
"hosts": [random.choice(hosts) for i in range(10)]}
for i in range(200):
data["_meta"]["hostvars"] = {
random.choice(hosts): {
rnd_string(): rnd_string() for i in range(10)}for i in range(10)}
data = json.dumps(data, indent=4)
# with open("big_json.txt", "a") as f:
# for i in data:
# f.write(i)
f = open("big_json111.txt", 'w')
f.write(data)
f.close()
inventory_generator()

0
selenium/__init__.py Normal file
View File

169
selenium/dashboard_test.py Normal file
View File

@ -0,0 +1,169 @@
import time
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
# from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from api.models import Inventory
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import os
import socket
# os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = '0.0.0.0:80'
class DashboardSeleniumTests(StaticLiveServerTestCase):
fixtures = ["tests/selenium/user.json"]
# live_server_url = 'localhost'
# live_server_url = 'http://{}:8000'.format(
# socket.gethostbyname(socket.gethostname())
# )
# host = socket.gethostbyname(socket.gethostname())
host = 'web'
@classmethod
def setUpClass(cls):
super().setUpClass()
# cls.selenium = WebDriver()
# cls.selenium.implicitly_wait(1)
# cls.selenium.maximize_window()
capabilities = DesiredCapabilities.CHROME.copy()
#
cls.selenium = webdriver.Remote(
command_executor="http://selenium:4444/wd/hub",
desired_capabilities=capabilities
)
cls.selenium.implicitly_wait(1)
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super().tearDownClass()
def test_workflow(self):
wait = 0.5
self.selenium.get('%s%s' % (self.live_server_url, '/dashboard/'))
print(self.live_server_url)
self.selenium.save_screenshot('screen.png')
print('done??')
# self.assertEqual(self.selenium.current_url, '%s%s' % (self.live_server_url, '/login/?next=/dashboard/'))
name = self.selenium.find_element_by_xpath('//*[@id="id_username"]')
name.send_keys("tester")
password = self.selenium.find_element_by_xpath('//*[@id="id_password"]')
password.send_keys("tester123")
button = self.selenium.find_element_by_xpath('//*[@id="login"]')
button.click()
# create inv
self.selenium.find_element_by_xpath('//*[@id="addInv"]').click()
self.selenium.find_element_by_css_selector('input[type="text"]').send_keys("tester123", Keys.RETURN)
# WebDriverWait(self.selenium, 10).until(
# lambda driver: self.selenium.find_element_by_xpath('//*[@id="ui-id-1"]/li/div[contains(text(), "tester123")]')
# )
# i = []
# while len(i) == 0:
# i = Inventory.objects.filter(inventory='tester123')
# print(i)
time.sleep(wait)
# select inv
self.selenium.find_element_by_css_selector('#eb div.ui-widget a span').click()
# time.sleep(100)
self.selenium.find_element_by_xpath('//*[@id="ui-id-1"]/li/div[contains(text(), "tester123")]').click()
# create gr
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="addGr"]').click()
self.selenium.find_element_by_css_selector('input[type="text"]').send_keys("test_group", Keys.RETURN)
# select gr
time.sleep(wait)
elem = self.selenium.find_element_by_css_selector('#sidepanel div.ui-widget a span')
elem.click()
# self.selenium.find_element_by_css_selector('#sidepanel div.ui-widget a span').click()
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[ @ id = "ui-id-{}"]/li/div[contains(text(), "test_group")]'.format(2)).click()
# except Exception as e:
# print(e)
# time.sleep(wait)
# create mach
self.selenium.find_element_by_xpath('//*[@id="eb"]/div[1]/a').click()
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="modal_content"]/h2/button').click()
# time.sleep(wait)
self.selenium.find_element_by_css_selector('#machform input[type="text"]').send_keys("test_mach", Keys.RETURN)
# WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath('//*[@id="modal_content"]/a'))
# time.sleep(wait)
time.sleep(1)
self.selenium.find_element_by_xpath('//*[@id="modal_content"]/a').click()
time.sleep(wait)
# create var
self.selenium.find_element_by_css_selector('#vars > button.plus').click()
# time.sleep(wait)
self.selenium.find_element_by_css_selector('#vars input[name="newVar"]').send_keys("test_var", Keys.RETURN)
# time.sleep(wait)
# self.selenium.find_element_by_css_selector('#vars input[name="newVal"]').send_keys("test_val")
time.sleep(wait)
# TODO add value
# create host
self.selenium.find_element_by_css_selector('#hosts > button.plus').click()
self.selenium.find_element_by_css_selector('#hostform a span').click()
time.sleep(wait)
self.selenium.find_element_by_css_selector('ul.ui-menu:nth-of-type(3) li div').click()
# self.selenium.find_element_by_xpath('//*ul[3]/li/div[contains(text(), "test_mach")]').click()
# time.sleep(wait)
self.selenium.find_element_by_css_selector('#hostform button').click()
# create gr
# time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="addGr"]').click()
self.selenium.find_element_by_css_selector('input[type="text"]').send_keys("test_child", Keys.RETURN)
# create child
time.sleep(1)
self.selenium.find_element_by_css_selector('#groups > button.plus').click()
self.selenium.find_element_by_css_selector('#child a span').click()
time.sleep(wait)
self.selenium.find_element_by_css_selector('ul.ui-menu:nth-of-type(3) li div').click()
# self.selenium.find_element_by_xpath('//*[@id="ui-id-18"]/li/div[contains(text(), "test_child")]').click()
# time.sleep(wait)
self.selenium.find_element_by_css_selector('#child button').click()
time.sleep(wait)
# del child
self.selenium.find_element_by_xpath('//*[@id="groups"]/table/tbody/tr/td[2]/a').click()
# del host
self.selenium.find_element_by_xpath('//*[@id="hosts"]/table/tbody/tr/td[2]/a').click()
# del var
self.selenium.find_element_by_xpath('//*[@id="vars"]/table/tbody/tr/td[3]/a').click()
# del gr
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="delGr"]').click()
# del inv
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="delInv"]').click()
time.sleep(wait)
# del mach
self.selenium.find_element_by_xpath('//*[@id="eb"]/div[1]/a').click()
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="modal_content"]/table/tbody/tr[1]/td[2]/button').click()
time.sleep(wait)
self.selenium.find_element_by_xpath('//*[@id="modal_content"]/a').click()
time.sleep(wait)

View File

@ -0,0 +1,46 @@
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.common.keys import Keys
from django.core import mail
from django.contrib.auth.models import User
from registration.models import Activation
from django.urls import reverse
import time
class MySeleniumTests(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.selenium = WebDriver()
cls.selenium.implicitly_wait(10)
cls.selenium.maximize_window()
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super().tearDownClass()
def test_login(self):
self.selenium.get('%s%s' % (self.live_server_url, '/registration/'))
elem = self.selenium.find_element_by_name("username")
elem.send_keys("test_user")
elem = self.selenium.find_element_by_name("email")
elem.send_keys("test_user@test.ru")
elem = self.selenium.find_element_by_name("password1")
elem.send_keys("qwerty123")
elem = self.selenium.find_element_by_name("password2")
elem.send_keys("qwerty123", Keys.RETURN)
time.sleep(1)
user = User.objects.get(username="test_user")
self.assertEqual(str(user), "test_user")
key = Activation.objects.all()[0]
act_url = key.get_absolute_url()
# print(mail.outbox[0].body)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "Deplodock. Завершение регистрации.")
self.assertEqual(mail.outbox[0].to[0], "test_user@test.ru")
self.assertRegexpMatches(mail.outbox[0].body, key.activation_key)
self.selenium.get('%s%s' % (self.live_server_url, act_url))
text = self.selenium.find_element_by_tag_name("body").text
self.assertEqual(text, "%s, ваш аккаунт активирован. Перейти в личный кабинет" % user)

3
selenium/user.json Normal file
View File

@ -0,0 +1,3 @@
[
{"model": "auth.user", "pk": 1, "fields": {"username": "tester", "password": "pbkdf2_sha256$100000$AJu3FQOhiYtW$WoGIroWBGo14YXEwFkU3yDhN0Uq8f6rc6e2kiHUg5B0=", "email": "tester@gmail.com"}}
]

0
trials/__init__.py Normal file
View File

View File

@ -0,0 +1,17 @@
import random
def get_random_string(length=12,
allowed_chars='abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
return ''.join(random.choice(allowed_chars) for i in range(length))
def get_random_secret_key():
"""
Return a 50 character random string usable as a SECRET_KEY setting value.
"""
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
return get_random_string(50, chars)
print(get_random_secret_key())

72
trials/my_test.py Normal file
View File

@ -0,0 +1,72 @@
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.test import TestCase
from api.models import Inventory, Group
from django.contrib.auth.models import User
import time
from django.db import transaction
class ProductivityTest(TestCase):
fixtures = ["tests/selenium/user.json"]
def test_massive_creation_base(self):
start = time.time()
user = User.objects.all()[0]
inventory = Inventory(user=user, inventory='inv')
inventory.save()
for i in range(20000):
group = Group(inventory=inventory, group="group_{}".format(i))
group.save()
time_is = time.time() - start
print("base: ", time_is)
# @transaction.atomic
def test_transaction(self):
start = time.time()
user = User.objects.all()[0]
inventory = Inventory(user=user, inventory='inv')
inventory.save()
with transaction.atomic():
for i in range(20000):
group = Group(inventory=inventory, group="group_{}".format(i))
group.clean_fields(exclude=['id', 'inventory'])
# group.setattr(f.attname, f.clean(raw_value, self))
# for i in group._meta.fields:
# print(i.name)
group.save()
time_is = time.time() - start
print("transaction_decorator: ", time_is)
# @transaction.atomic
def test_bulk(self):
start = time.time()
user = User.objects.all()[0]
inventory = Inventory(user=user, inventory='inv')
inventory.save()
group_list = []
# Group.objects.bulk_create([
# Group(inventory=inventory, group="group_{}".format(group)) for group in range(20000)
# if Group(inventory=inventory, group="group_{}".format(group)).clean_fields(exclude=['id', 'inventory']) is None
# ])
for i in range(20000):
group = Group(inventory=inventory, group="group_{}".format(i))
group.clean_fields(exclude=['id', 'inventory'])
# group.save()
# group = Group.objects.get(inventory=inventory, group="group_{}".format(i))
group_list.append(group)
Group.objects.bulk_create(group_list)
# for i in range(20000):
# group = Group.objects.get(inventory=inventory, group="group_{}".format(i))
# group.save()
time_is = time.time() - start
print("bulk_decorator: ", time_is)