Notebooks >> Scripts
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

380 lines
14 KiB

import builtins
import io
import os
import pytest
import unittest
import sys
from contextlib import contextmanager, redirect_stdout
import requests
from kinto_http import Client, exceptions
from kinto_wizard.__main__ import main
def load(server, auth, file, bucket=None, collection=None, extra=None):
cmd = 'kinto-wizard {} --server={} --auth={}'
if bucket:
cmd += ' --bucket={}'.format(bucket)
if collection:
cmd += ' --collection={}'.format(collection)
if extra:
cmd += ' ' + extra
load_cmd = cmd.format("load {}".format(file), server, auth)
sys.argv = load_cmd.strip().split(" ")
return main()
def dump(server, auth, bucket=None, collection=None):
cmd = 'kinto-wizard {} --server={} --auth={}'
dump_cmd = cmd.format("dump --full", server, auth)
if bucket:
dump_cmd += ' --bucket={}'.format(bucket)
if collection:
dump_cmd += ' --collection={}'.format(collection)
sys.argv = dump_cmd.split(" ")
output = io.StringIO()
with redirect_stdout(output):
main()
output.flush()
# Check that identical to original file.
return output.getvalue()
def validate(filename):
sys.argv = ['kinto-wizard', 'validate', filename]
return main()
class FunctionalTest(unittest.TestCase):
server = os.getenv("SERVER_URL", "http://localhost:8888/v1")
auth = os.getenv("AUTH", "user:pass")
file = os.getenv("FILE", "tests/kinto.yaml")
def setUp(self):
requests.post(self.server + "/__flush__")
def load(self, bucket=None, collection=None, filename=None, extra=None):
return load(self.server, self.auth, filename or self.file, bucket, collection, extra)
def dump(self, bucket=None, collection=None):
return dump(self.server, self.auth, bucket, collection)
def validate(self, filename=None, code=0):
try:
validate(filename or self.file)
except SystemExit as e:
if e.code == code:
return
else:
self.fail(f"Unexpected validation status {e.code} != {code}")
class DryRunLoad(FunctionalTest):
def test_dry_round_trip(self):
cmd = 'kinto-wizard {} --server={} --auth={} --dry-run'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
client = Client(server_url=self.server, auth=tuple(self.auth.split(':')))
with pytest.raises(exceptions.KintoException):
client.get_bucket(id="staging")
@contextmanager
def mockInput(mock):
original_input = builtins.input
builtins.input = lambda _: mock
yield
builtins.input = original_input
class SimpleDump(FunctionalTest):
def test_round_trip(self):
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
dump_cmd = cmd.format("dump", self.server, self.auth)
sys.argv = dump_cmd.split(" ")
output = io.StringIO()
with redirect_stdout(output):
main()
output.flush()
# Check that identical to original file.
generated = output.getvalue()
with open(self.file) as f:
assert f.read() == generated
class FullDump(FunctionalTest):
file = os.getenv("FILE", "tests/kinto-full.yaml")
def test_round_trip(self):
# Load some data
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
cmd = 'kinto-wizard {} --server={} --auth={} --full'
load_cmd = cmd.format("dump", self.server, self.auth)
sys.argv = load_cmd.split(" ")
output = io.StringIO()
with redirect_stdout(output):
main()
output.flush()
# Check that identical to original file.
generated = output.getvalue()
with open(self.file) as f:
assert f.read() == generated
def test_round_trip_with_client_wins(self):
# Load some data
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
# Change something that could make the server to fail.
client = Client(server_url=self.server, auth=tuple(self.auth.split(':')))
client.update_record(bucket='build-hub', collection='archives',
id='0831d549-0a69-48dd-b240-feef94688d47', data={})
record = client.get_record(bucket='build-hub', collection='archives',
id='0831d549-0a69-48dd-b240-feef94688d47')
assert set(record['data'].keys()) == {'id', 'last_modified'}
cmd = 'kinto-wizard {} --server={} -D --auth={} --force'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
record = client.get_record(bucket='build-hub', collection='archives',
id='0831d549-0a69-48dd-b240-feef94688d47')
assert set(record['data'].keys()) != {'id', 'last_modified'}
def test_round_trip_with_client_wins_and_delete_missing_records(self):
# Load some data
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
# Change something that could make the server to fail.
client = Client(server_url=self.server, auth=tuple(self.auth.split(':')))
client.create_record(bucket='build-hub', collection='archives',
id='8031d549-0a69-48dd-b240-feef94688d47', data={})
cmd = 'kinto-wizard {} --server={} -D --auth={} --force --delete-records'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
with pytest.raises(exceptions.KintoException) as exc:
client.get_record(bucket='build-hub', collection='archives',
id='8031d549-0a69-48dd-b240-feef94688d47')
assert "'Not Found'" in str(exc.value)
def test_round_trip_with_delete_missing_records_ask_for_confirmation(self):
# Load some data
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
# Change something that could make the server to fail.
client = Client(server_url=self.server, auth=tuple(self.auth.split(':')))
client.create_record(bucket='build-hub', collection='archives',
id='8031d549-0a69-48dd-b240-feef94688d47', data={})
cmd = 'kinto-wizard {} --server={} -D --auth={} --delete-records'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
with mockInput('yes'):
main()
with pytest.raises(exceptions.KintoException) as exc:
client.get_record(bucket='build-hub', collection='archives',
id='8031d549-0a69-48dd-b240-feef94688d47')
assert "'Not Found'" in str(exc.value)
def test_round_trip_with_delete_missing_records_handle_misconfirmation(self):
# Load some data
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
# Change something that could make the server to fail.
client = Client(server_url=self.server, auth=tuple(self.auth.split(':')))
client.create_record(bucket='build-hub', collection='archives',
id='8031d549-0a69-48dd-b240-feef94688d47', data={})
cmd = 'kinto-wizard {} --server={} -D --auth={} --delete-records'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
with mockInput('no'):
with pytest.raises(SystemExit):
main()
class DataRecordsDump(FunctionalTest):
file = os.getenv("FILE", "tests/kinto-full.yaml")
def test_round_trip(self):
# Load some data
cmd = 'kinto-wizard {} --server={} --auth={}'
load_cmd = cmd.format("load {}".format(self.file),
self.server, self.auth)
sys.argv = load_cmd.split(" ")
main()
cmd = 'kinto-wizard {} --server={} --auth={} --data --records'
load_cmd = cmd.format("dump", self.server, self.auth)
sys.argv = load_cmd.split(" ")
output = io.StringIO()
with redirect_stdout(output):
main()
output.flush()
# Check that identical to original file.
generated = output.getvalue()
with open(self.file) as f:
assert f.read() == generated
class BucketCollectionSelectionableDump(FunctionalTest):
file = os.getenv("FILE", "tests/dumps/dump-full.yaml")
def test_validate(self):
self.validate()
def test_round_trip_with_bucket_selection_on_load(self):
self.load(bucket="natim")
generated = self.dump()
with open("tests/dumps/dump-natim.yaml") as f:
assert f.read() == generated
def test_round_trip_with_bucket_selection(self):
self.load()
generated = self.dump(bucket="natim")
with open("tests/dumps/dump-natim.yaml") as f:
assert f.read() == generated
def test_round_trip_with_bucket_collection_selection_on_load(self):
self.load(bucket="natim", collection="toto")
generated = self.dump()
with open("tests/dumps/dump-natim-toto-groups.yaml") as f:
assert f.read() == generated
def test_round_trip_with_bucket_collection_selection(self):
self.load()
generated = self.dump(bucket="natim", collection="toto")
with open("tests/dumps/dump-natim-toto.yaml") as f:
assert f.read() == generated
def test_round_trip_with_collection_selection_on_load(self):
self.load(collection="toto")
generated = self.dump()
with open("tests/dumps/dump-toto-groups.yaml") as f:
assert f.read() == generated
def test_round_trip_with_collection_selection(self):
self.load()
generated = self.dump(collection="toto")
with open("tests/dumps/dump-toto.yaml") as f:
assert f.read() == generated
def test_wizard_can_handle_dates(self):
self.load(bucket="date")
generated = self.dump()
with open("tests/dumps/dump-date.yaml") as f:
assert f.read() == generated
class YAMLReferenceSupportTest(FunctionalTest):
file = os.getenv("FILE", "tests/dumps/with-references.yaml")
def test_validate(self):
self.validate()
def test_file_can_have_yaml_references(self):
self.load()
client = Client(server_url=self.server, auth=tuple(self.auth.split(':')))
collection = client.get_collection(bucket="main", id="certificates")
assert 'url' in collection['data']['schema']['properties']
collection = client.get_collection(bucket="main", id="addons")
assert 'url' in collection['data']['schema']['properties']
# the anchor did not get interpreted as a bucket:
with self.assertRaises(exceptions.KintoException):
client.get_collection(bucket="attachment-schema")
class WrongSchemaValidationTest(FunctionalTest):
file = "tests/dumps/wrong-schema.yaml"
def test_validate(self):
self.validate(code=1)
class MiscUpdates(FunctionalTest):
def get_client(self):
return Client(server_url=self.server, auth=tuple(self.auth.split(':')))
def test_validate(self):
# This dump has a schema that requires `title` field, and a record doesn't have it.
self.validate(filename="tests/dumps/with-schema-1.yaml", code=1)
# This dump has a schema that does not require `title` field, so the dump is valid.
self.validate(filename="tests/dumps/with-schema-2.yaml")
def test_raises_with_4xx_error_in_batch(self):
with pytest.raises(exceptions.KintoBatchException):
self.load(filename="tests/dumps/with-schema-1.yaml")
records = self.get_client().get_records(bucket="natim", collection="toto")
assert len(records) == 0
def test_ignore_batch_4xx_errors_if_specified(self):
# Raises a KintoBatchException in case of error
self.load(filename="tests/dumps/with-schema-1.yaml", extra="--ignore-batch-4xx")
def test_record_updates(self):
self.load(filename="tests/dumps/with-schema-1.yaml", extra="--ignore-batch-4xx")
client = self.get_client()
client.create_record(data={'title': 'titi', 'last_modified': 1496132479110},
id="e2686bac-c45e-4144-9738-edfeb3d9da6d",
collection='toto', bucket='natim')
self.load(filename="tests/dumps/with-schema-2.yaml")
r = client.get_record(id="e2686bac-c45e-4144-9738-edfeb3d9da6d",
collection='toto', bucket='natim')
assert r["data"]["title"] == "toto"
def test_group_updates(self):
self.load(filename="tests/dumps/with-groups.yaml")
client = self.get_client()
client.update_group(data={"members": ["alexis", "mathieu", "remy"]},
id="toto", bucket="natim")
self.load(filename="tests/dumps/with-groups.yaml")
r = client.get_group(id="toto", bucket='natim')
assert r["data"]["members"] == ["alexis", "mathieu"]