Esempio n. 1
0
    def test_api_create_reference_002(server):
        """Create one Reference resource.

        Send POST /references to create a new reference. Created resource
        is sent in the POST method resource ``data`` attribute as object. The
        HTTP response must send the created resource in the resource ``data``
        attribute as list of objects.
        """

        storage = {'data': [Storage.gitlog]}
        storage['data'][0]['uuid'] = Content.UUID1
        request_body = {
            'data': {
                'type': 'reference',
                'attributes': Request.gitlog
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '580'
        }
        expect_body = {
            'data': [{
                'type': 'reference',
                'id': Content.UUID1,
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
    def test_api_search_solution_008(server):
        """Search solution with GET.

        Send GET /solutions to return only defined attributes. In this case
        the fields are defined by setting the 'fields' parameter multiple
        times.
        """

        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '205'
        }
        expect_body = {
            'meta': {
                'count': 1,
                'limit': 1,
                'offset': 0,
                'total': 2
            },
            'data': [{
                'type': 'solution',
                'id': Solution.NGINX_UUID,
                'attributes': {
                    field: Storage.dnginx[field]
                    for field in ['brief', 'category']
                }
            }]
        }
        result = testing.TestClient(server.server.api).simulate_get(
            path='/api/snippy/rest/solutions',
            headers={'accept': 'application/json'},
            query_string=
            'sall=debug&limit=1&sort=-brief&fields=brief&fields=category')
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
    def test_cli_import_reference_012(snippy):
        """Import reference based on message digest.

        Import defined reference based on message digest. In this case the
        content category is accidentally specified as 'snippet'. This should
        still import the content in reference category.
        """

        content = {'data': [Content.deepcopy(Reference.GITLOG)]}
        content['data'][0]['links'] = ('https://updated-link.html', )
        content['data'][0]['updated'] = Content.PYTEST_TIME
        content['data'][0][
            'digest'] = 'fafd46eca7ca239bcbff8f1ba3e8cf806cadfbc9e267cdf6ccd3e23e356f9f8d'
        file_content = Content.get_file_content(Content.TEXT, content)
        with mock.patch('snippy.content.migrate.open',
                        file_content,
                        create=True) as mock_file:
            cause = snippy.run([
                'snippy', 'import', '--scat', 'snippet', '-d',
                '5c2071094dbfaa33', '-f', 'one-reference.text'
            ])
            assert cause == Cause.ALL_OK
            Content.assert_storage(content)
            mock_file.assert_called_once_with('one-reference.text', 'r')
Esempio n. 4
0
    def test_debug_print_001(capsys):
        """Test printing the content.

        Test printing content with print. This is a development test which
        must directly print the snippets with the test case helper method.
        """

        output = (
            '1. Remove all docker containers with volumes @docker [54e41e9b52a02b63]',
            '', '   $ docker rm --volumes $(docker ps --all --quiet)', '',
            '   # cleanup,container,docker,docker-ce,moby',
            '   > https://docs.docker.com/engine/reference/commandline/rm/',
            '', '   ! category    : snippet',
            '   ! created     : 2017-10-14T19:56:31.000001+00:00',
            '   ! description : ',
            '   ! digest      : 54e41e9b52a02b631b5c65a6a053fcbabc77ccd42b02c64fdfbc76efdb18e319 (True)',
            '   ! filename    : ',
            '   ! id          : a1cd5827-b6ef-4067-b5ac-3ceac07dde9f',
            '   ! languages   : ', '   ! name        : ',
            '   ! source      : ',
            '   ! updated     : 2017-10-14T19:56:31.000001+00:00',
            '   ! uuid        : 11cd5827-b6ef-4067-b5ac-3ceac07dde9f',
            '   ! versions    : ', '',
            '2. Remove docker image with force @docker [53908d68425c61dc]', '',
            '   $ docker rm --force redis', '',
            '   # cleanup,container,docker,docker-ce,moby',
            '   > https://docs.docker.com/engine/reference/commandline/rm/',
            '   > https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes',
            '', '   ! category    : snippet',
            '   ! created     : 2017-10-14T19:56:31.000001+00:00',
            '   ! description : ',
            '   ! digest      : 53908d68425c61dc310c9ce49d530bd858c5be197990491ca20dbe888e6deac5 (True)',
            '   ! filename    : ',
            '   ! id          : a2cd5827-b6ef-4067-b5ac-3ceac07dde9f',
            '   ! languages   : ', '   ! name        : ',
            '   ! source      : ',
            '   ! updated     : 2017-10-14T19:56:31.000001+00:00',
            '   ! uuid        : 12cd5827-b6ef-4067-b5ac-3ceac07dde9f',
            '   ! versions    : ', '', '# collection meta', '   ! total : 2')
        print(Content.output())  # Part of the test.
        out, err = capsys.readouterr()
        out = Helper.remove_ansi(out)
        assert Const.NEWLINE.join(output) in out
        assert not err
Esempio n. 5
0
    def create_defaults(snippy):
        """Add default snippets for testing purposes."""

        file_content = Content.get_file_content(Content.TEXT,
                                                {'data': [Snippet.REMOVE]})
        with mock.patch('snippy.content.migrate.open',
                        file_content,
                        create=True):
            cause = snippy.run(['snippy', 'import', '-f', 'remove.txt'] +
                               Content.db_cli_params())
            assert cause == Cause.ALL_OK

        file_content = Content.get_file_content(Content.TEXT,
                                                {'data': [Snippet.FORCED]})
        with mock.patch('snippy.content.migrate.open',
                        file_content,
                        create=True):
            cause = snippy.run(['snippy', 'import', '-f', 'forced.txt'] +
                               Content.db_cli_params())
            assert cause == Cause.ALL_OK

        file_content = Content.get_file_content(Content.TEXT,
                                                {'data': [Solution.BEATS]})
        with mock.patch('snippy.content.migrate.open',
                        file_content,
                        create=True):
            cause = snippy.run(['snippy', 'import', '-f', 'beats.txt'] +
                               Content.db_cli_params())
            assert cause == Cause.ALL_OK

        file_content = Content.get_file_content(Content.TEXT,
                                                {'data': [Solution.NGINX]})
        with mock.patch('snippy.content.migrate.open',
                        file_content,
                        create=True):
            cause = snippy.run(['snippy', 'import', '-f', 'nginx.txt'] +
                               Content.db_cli_params())
            assert cause == Cause.ALL_OK
Esempio n. 6
0
    def test_api_update_reference_002(server):
        """Update one reference with PUT request.

        Send PUT /references/{id} to update existing resource. The PUT
        request contains only the mandatory links attribute. All other
        attributes must be set to their default values in the HTTP response.
        """

        storage = {
            'data': [{
                'category':
                'reference',
                'data': (),
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': (),
                'links':
                Reference.PYTEST['links'],
                'source':
                '',
                'versions': (),
                'languages': (),
                'filename':
                '',
                'created':
                Content.GITLOG_TIME,
                'updated':
                Content.PYTEST_TIME,
                'uuid':
                Reference.GITLOG_UUID,
                'digest':
                '4a868cc74e3d32a4340e1a2fd17d0df815777c67f827aeedbb35869b740dd720'
            }]
        }
        request_body = {
            'data': {
                'type': 'snippet',
                'attributes': {
                    'links': storage['data'][0]['links'],
                }
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '667'
        }
        expect_body = {
            'links': {
                'self':
                'http://falconframework.org/api/snippy/rest/references/' +
                Reference.GITLOG_UUID
            },
            'data': {
                'type': 'reference',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }
        }
        result = testing.TestClient(server.server.api).simulate_put(
            path='/api/snippy/rest/references/5c2071094dbfaa33',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
    def test_cli_create_snippet_012(snippy, editor_data):
        """Create snippet with editor.

        Create a new snippet and define tags and brief already from command
        line interface. Other fields must have the default template content
        that is normally presented for the user when content is created with
        editor.

        The groups, links and description default values are not changed from
        default examples. These values must result tool internal defaults when
        content is stored.

        User fills the content data from editor so the content is stored.

        Editor must be used by default.
        """

        content = {
            'data': [{
                'category':
                'snippet',
                'data': ('docker rm --volumes $(docker ps --all --quiet)', ),
                'brief':
                'Brief from cli',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': ('cli', 'from', 'tags'),
                'links': (),
                'source':
                '',
                'versions': (),
                'languages': (),
                'filename':
                '',
                'created':
                '2017-10-14T19:56:31.000001+00:00',
                'updated':
                '2017-10-14T19:56:31.000001+00:00',
                'uuid':
                'a1cd5827-b6ef-4067-b5ac-3ceac07dde9f',
                'digest':
                'a020eb12a278e4426169360af1e124fb989747fd8a9192c293c938cea05798fa'
            }]
        }
        template = (
            '# Brief from cli @groups', '',
            '> Add a description that defines the content in one chapter.', '',
            '> [1] https://www.example.com/add-links-here.html', '',
            '`$ Markdown commands are defined between backtics and prefixed by a dollar sign`',
            '', '## Meta', '', '> category  : snippet  ',
            'created   : 2017-10-14T19:56:31.000001+00:00  ',
            'digest    : 023dc3bf754064bc5c3692cf535a769f402b187e14ebfb7e64273f6caf03ec6e  ',
            'filename  : example-content.md  ',
            'languages : example-language  ',
            'name      : example content handle  ',
            'source    : https://www.example.com/source.md  ',
            'tags      : cli,from,tags  ',
            'updated   : 2017-10-14T19:56:31.000001+00:00  ',
            'uuid      : a1cd5827-b6ef-4067-b5ac-3ceac07dde9f  ',
            'versions  : example=3.9.0,python>=3  ', '')
        edited = (
            '# Brief from cli @groups', '',
            '> Add a description that defines the content in one chapter.', '',
            '> [1] https://www.example.com/add-links-here.html', '',
            '`$ docker rm --volumes $(docker ps --all --quiet)`', '',
            '## Meta', '', '> category : snippet  ',
            'created  : 2017-10-14T19:56:31.000001+00:00  ',
            'digest   : fdbf285d091a8c46cf491da675ecfeda38f7796ef034124b357f49737963cd19  ',
            'filename :  ', 'language :  ', 'name     :  ', 'source   :  ',
            'tags     : cli,from,tags  ',
            'updated  : 2017-10-14T19:56:31.000001+00:00  ',
            'uuid     : a1cd5827-b6ef-4067-b5ac-3ceac07dde9f  ',
            'versions :  ', '')
        editor_data.return_value = Const.NEWLINE.join(edited)
        cause = snippy.run([
            'snippy', 'create', '-t', 'tags,from,cli', '-b', 'Brief from cli'
        ])
        assert cause == Cause.ALL_OK
        editor_data.assert_called_with(Const.NEWLINE.join(template))
        Content.assert_storage(content)
Esempio n. 8
0
    def test_api_create_solution_009(server):
        """Create one solution from API.

        Send POST /solutions to create a new resource. In this case every
        attribute has additional leading and trailing whitespaces. Trimming
        must be done all fields with the exception of data field. In case of
        data field, there must be only one newline at the end of solution and
        the extra white spaces must be left as is.

        The ``tags`` and ``links`` attributes must be sorted when stored.
        """

        storage = {
            'data': [{
                'category':
                'solution',
                'data': ('     first row   ', '   second row  ', ''),
                'brief':
                'short brief',
                'description':
                'long description',
                'name':
                'short name',
                'groups': ('python', ),
                'tags': ('atabs', 'bspaces'),
                'links': ('alink2', 'blink1'),
                'source':
                'short source link',
                'versions': ('versions==1.1-alpha', ),
                'filename':
                'shortfilename.yaml',
                'created':
                Content.REGEXP_TIME,
                'updated':
                Content.REGEXP_TIME,
                'uuid':
                Content.UUID1,
                'digest':
                '2fba73d95146c736a2717e18758fd1871ccb9aa68171614435365f5ad5075ba8'
            }]
        }
        request_body = {
            'data': [{
                'type': 'solution',
                'attributes': {
                    'data':
                    ['     first row   ', '   second row  ', '', '', ''],
                    'brief': ' short brief  ',
                    'description': ' long description  ',
                    'name': '  short name   ',
                    'groups': [
                        '    python   ',
                    ],
                    'tags': ['  bspaces   ', '  atabs    '],
                    'links': ['  blink1  ', '    alink2   '],
                    'source': '  short source link   ',
                    'versions': ['  versions==1.1-alpha   '],
                    'filename': '  shortfilename.yaml   '
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '658'
        }
        expect_body = {
            'data': [{
                'type': 'solution',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/solutions',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 9
0
    def test_cli_update_snippet_017(snippy, editor_data):
        """Update snippet with editor.

        Update existing snippet directly from command line. In this case the
        snippet contains multiple comments which are same. The update is made
        in Markdown format and editor must be able to show the content. There
        are no changes and the parser must notice that the content was not
        updated.
        """

        Content.store({
            'category':
            Content.SNIPPET,
            'data': [
                "find . -iregex '.*\\(py\\|robot\\)'  #  Find files.",
                "find . -iregex '.*\\(py\\|robot\\)' -print0 | wc -l --files0-from=-  #  Find files and count lines.",
                "find . -iregex '.*\\(py\\|robot\\)' -print0 | wc -l --files0-from=- | tail -n 1",
                "find . -name '*.py' -print0 | wc -l --files0-from=-  #  Find files and count lines.",
                "find . -name '*.py' -print0 | wc -l --files0-from=- | tail -n 1",
                "find . -name '*.py' -exec cat {} + | wc -l  #  Find files and count lines."
            ],
            'brief':
            'Find files and count lines',
            'description':
            'Find files with or without regexp pattern and count lines.',
            'groups': ['linux'],
            'tags': ['find', 'linux', 'regexp'],
            'digest':
            'dae4e22c3c3858b5616a29be11916112a16994e30bc3e4b93b069bc9a772d889'
        })
        content = {
            'data': [{
                'category':
                'snippet',
                'data':
                ("find . -iregex '.*\\(py\\|robot\\)'  #  Find files.",
                 "find . -iregex '.*\\(py\\|robot\\)' -print0 | wc -l --files0-from=-  #  Find files and count lines.",
                 "find . -iregex '.*\\(py\\|robot\\)' -print0 | wc -l --files0-from=- | tail -n 1",
                 "find . -name '*.py' -print0 | wc -l --files0-from=-  #  Find files and count lines.",
                 "find . -name '*.py' -print0 | wc -l --files0-from=- | tail -n 1",
                 "find . -name '*.py' -exec cat {} + | wc -l  #  Find files and count lines."
                 ),
                'brief':
                'Find files and count lines',
                'description':
                'Find files with or without regexp pattern and count lines.',
                'name':
                '',
                'groups': ('linux', ),
                'tags': ('find', 'linux', 'regexp'),
                'links': (),
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                '2018-03-02T02:02:02.000001+00:00',
                'updated':
                '2018-03-02T02:02:02.000001+00:00',
                'uuid':
                'a1cd5827-b6ef-4067-b5ac-3ceac07dde9f',
                'digest':
                'dae4e22c3c3858b5616a29be11916112a16994e30bc3e4b93b069bc9a772d889'
            }]
        }
        template = (
            '# Find files and count lines @linux', '',
            '> Find files with or without regexp pattern and count lines.', '',
            '> ', '', '- Find files.', '',
            '    `$ find . -iregex \'.*\\(py\\|robot\\)\'`', '',
            '- Find files and count lines.', '',
            '    `$ find . -iregex \'.*\\(py\\|robot\\)\' -print0 | wc -l --files0-from=-`',
            '', '- <not documented>', '',
            '    `$ find . -iregex \'.*\\(py\\|robot\\)\' -print0 | wc -l --files0-from=- | tail -n 1`  ',
            '', '- Find files and count lines.', '',
            '    `$ find . -name \'*.py\' -print0 | wc -l --files0-from=-`',
            '', '- <not documented>', '',
            '    `$ find . -name \'*.py\' -print0 | wc -l --files0-from=- | tail -n 1`  ',
            '', '- Find files and count lines.', '',
            '    `$ find . -name \'*.py\' -exec cat {} + | wc -l`', '',
            '## Meta', '', '> category : snippet  ',
            'created  : 2018-03-02T02:02:02.000001+00:00  ',
            'digest   : dae4e22c3c3858b5616a29be11916112a16994e30bc3e4b93b069bc9a772d889  ',
            'filename :  ', 'name     :  ', 'source   :  ',
            'tags     : find,linux,regexp  ',
            'updated  : 2018-03-02T02:02:02.000001+00:00  ',
            'uuid     : a1cd5827-b6ef-4067-b5ac-3ceac07dde9f  ',
            'versions :  ', '')
        editor_data.return_value = '\n'.join(template)
        cause = snippy.run(['snippy', 'update', '-d', 'dae4e22c3c3858b5'])
        assert cause == Cause.ALL_OK
        editor_data.assert_called_with('\n'.join(template))
        Content.assert_storage(content)
Esempio n. 10
0
    def test_api_update_snippet_003(server):
        """Update one snippet with PUT request.

        Send PUT /snippets/{id} to update existing resource with specified
        digest. The PUT request contains only the mandatory data attribute.
        All other attributes must be set to their default values.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data':
                Snippet.REMOVE['data'],
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': (),
                'links': (),
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                Content.FORCED_TIME,
                'updated':
                Content.REMOVE_TIME,
                'uuid':
                '12cd5827-b6ef-4067-b5ac-3ceac07dde9f',
                'digest':
                '26128ea95707a3a2623bb2613a17f50e29a5ab5232b8ba7ca7f1c96cb1ea5c58'
            }]
        }
        request_body = {
            'data': {
                'type': 'snippet',
                'attributes': {
                    'data': Snippet.REMOVE['data'],
                }
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '643'
        }
        expect_body = {
            'links': {
                'self':
                'http://falconframework.org/api/snippy/rest/snippets/' +
                Snippet.FORCED_UUID
            },
            'data': {
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }
        }
        result = testing.TestClient(server.server.api).simulate_put(
            path='/api/snippy/rest/snippets/53908d68425c61dc',
            headers={'accept': 'application/vnd.api+json'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 11
0
    def test_api_create_snippet_023(server):
        """Create one snippet with POST.

        Send POST /snippets to create a new resource. The ``groups`` field
        is not defined at all in the HTTP request. The default value for this
        attribute must be always added if no value is provided by client.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data': ('test', ),
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': (),
                'links': (),
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                '2017-10-14T19:56:31.000001+00:00',
                'updated':
                '2017-10-14T19:56:31.000001+00:00',
                'uuid':
                Content.UUID1,
                'digest':
                '4531ade7232dda7debd7ec3a20b2669afb57d665bd058184155442de203c76af',
            }]
        }
        request_body = {
            'data': [{
                'type': 'snippet',
                'attributes': {
                    'data': ['test']
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '492'
        }
        expect_body = {
            'data': [{
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets',
            headers={'accept': 'application/json'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 12
0
    def test_api_create_snippet_022(server):
        """Create new snippet with duplicated content field values.

        Send POST /snippets to create a new resource. In this case the
        resource attributes contain duplicated values. For example, there is
        a tag 'python' included twice in the ``tags`` attribute. Only unique
        values in attributes in array context must be added.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data': ('duplicated field values', ),
                'brief':
                'short brief',
                'description':
                '',
                'name':
                '',
                'groups': ('docker', 'python'),
                'tags': ('pypy', 'swarm'),
                'links':
                ('http://www.dot.com/link1', 'http://www.dot.com/link2'),
                'source':
                '',
                'versions': ('docker-ce>17.09.2', ),
                'filename':
                '',
                'created':
                '2017-10-14T19:56:31.000001+00:00',
                'updated':
                '2017-10-14T19:56:31.000001+00:00',
                'uuid':
                Content.UUID1,
                'digest':
                '800af62696ab9592c23dd5674642b91854e73a0c23f7659ac553de7fc66400d5'
            }]
        }
        request_body = {
            'data': [{
                'type': 'snippet',
                'attributes': {
                    'data': ['duplicated field values'],
                    'brief':
                    'short brief',
                    'description':
                    '',
                    'groups': ['docker', 'docker', 'python'],
                    'tags': ['swarm', 'swarm', 'pypy'],
                    'links': [
                        'http://www.dot.com/link2', 'http://www.dot.com/link2',
                        'http://www.dot.com/link1'
                    ],
                    'versions': ['docker-ce>17.09.2']
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '619'
        }
        expect_body = {
            'data': [{
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets',
            headers={
                'accept': 'application/vnd.api+json',
                'content-type': 'application/vnd.api+json; charset=UTF-8'
            },
            body=json.dumps(request_body, ensure_ascii=False))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 13
0
    def test_api_create_snippet_021(server):
        """Create one Snippet resource.

        Send POST /snippets to create new resource with data that have line
        breaks in the middle of the snippet which must not be interpolated to
        newlines.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data':
                ('docker rm $(docker\\nps \\n --all -q -f status=exited)', ),
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': (),
                'links': (),
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                '2017-10-14T19:56:31.000001+00:00',
                'updated':
                '2017-10-14T19:56:31.000001+00:00',
                'uuid':
                Content.UUID1,
                'digest':
                'c10b8614d264ed75ad3b671526efb9718895974291627b4fd21307051c6928c1'
            }]
        }
        request_body = {
            'data': [{
                'type': 'snippet',
                'attributes': {
                    'data': [
                        'docker rm $(docker\\nps \\n --all -q -f status=exited)\n'
                    ]
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '542'
        }
        expect_body = {
            'data': [{
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets',
            headers={'accept': 'application/json'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 14
0
    def test_api_create_snippet_020(server):
        """Create one Snippet resource.

        Send POST /snippets to create new resource. In this case all fields
        have unnecessary leading and trailing whitespaces which are removed.
        Tags and links must be sorted.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data': ('first row', 'second row'),
                'brief':
                'short brief',
                'description':
                'long description',
                'name':
                'short name',
                'groups': ('python', ),
                'tags': ('spaces', 'tabs'),
                'links': ('link1', 'link2'),
                'source':
                'short source link',
                'versions': ('version==1.1.1', ),
                'filename':
                'shortfilename.yaml',
                'created':
                Content.REGEXP_TIME,
                'updated':
                Content.REGEXP_TIME,
                'uuid':
                Content.UUID1,
                'digest':
                'b04d8c1f2913fc3c501e129505265986f1294da0cd3e9f758561cf5443ccf69f'
            }]
        }
        request_body = {
            'data': [{
                'type': 'snippet',
                'attributes': {
                    'data': ['     first row   ', '   second row  '],
                    'brief': ' short brief  ',
                    'description': ' long description  ',
                    'name': '  short name   ',
                    'groups': [
                        '    python   ',
                    ],
                    'tags': ['  tabs   ', '  spaces    '],
                    'links': ['  link2  ', '    link1   '],
                    'source': '  short source link   ',
                    'versions': ['  version==1.1.1   '],
                    'filename': '  shortfilename.yaml   '
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '630'
        }
        expect_body = {
            'data': [{
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 15
0
    def test_cli_performance(self, snippy_perf, capsys, caplog):
        """Test CLI performance.

        Verify performance of the tool on a rough scale. The intention
        is to keep a reference test that is just iterated few times and
        the time consumed is measured. This is more for manual analysis
        than automation as of now.

        Reference PC:   1 loop :  0.0252 /   55 loop :  1.0865 / 100 loop : 1.9484
        Reference PC: 880 loop : 17.6897 / 1000 loop : 19.6802

        The reference is with sqlite database in memory as with all tests.
        There is naturally jitter in results and the values are as of now
        hand picked from few examples.

        Note that when run on Python2, will use sqlite database in disk
        that is naturally slower than memory database.

        No errors should be printed and the runtime should be below 10
        seconds. The runtime is intentionally set 15 times higher value
        than with the reference PC to cope with slow test envrironments.
        """

        start = time.time()
        for _ in range(55):
            self.create_defaults(snippy_perf)
            Content.assert_storage_size(4)

            # Search all content.
            cause = snippy_perf.run(
                ['snippy', 'search', '--scat', 'all', '--sall', '.'] +
                Content.db_cli_params())
            assert cause == Cause.ALL_OK

            # Delete all content.
            cause = snippy_perf.run(
                ['snippy', 'delete', '-d', '54e41e9b52a02b63'] +
                Content.db_cli_params())
            assert cause == Cause.ALL_OK
            cause = snippy_perf.run(
                ['snippy', 'delete', '-d', '53908d68425c61dc'] +
                Content.db_cli_params())
            assert cause == Cause.ALL_OK
            cause = snippy_perf.run(
                ['snippy', 'delete', '-d', '4346ba4c79247430'] +
                Content.db_cli_params())
            assert cause == Cause.ALL_OK
            cause = snippy_perf.run(
                ['snippy', 'delete', '-d', '6cfe47a8880a8f81'] +
                Content.db_cli_params())
            assert cause == Cause.ALL_OK
            Content.assert_storage(None)

        runtime = time.time() - start
        out, err = capsys.readouterr()
        print("====================================")
        print("Runtime %.4f" % runtime)
        print("There are %d rows in stdout" % len(out))
        print("There are %d rows in stderr" % len(err))
        print("====================================")

        assert not err
        assert not caplog.records[:]
        assert runtime < 15
Esempio n. 16
0
    def test_api_create_reference_013(server):
        """Create two References with two POST methods.

        Send POST /references twice to create two new references. In this case
        the HTTP response for each POST request must contain only the created
        resource.
        """

        storage = {'data': [Storage.gitlog]}
        storage['data'][0]['uuid'] = Content.UUID1
        request_body = {
            'data': {
                'type': 'reference',
                'attributes': Request.gitlog
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '597'
        }
        expect_body = {
            'data': [{
                'type': 'reference',
                'id': Content.UUID1,
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)

        storage = {'data': [Storage.pytest, Storage.gitlog]}
        storage['data'][0]['uuid'] = Content.UUID2
        storage['data'][1]['uuid'] = Content.UUID1
        request_body = {
            'data': {
                'type': 'reference',
                'attributes': Request.pytest
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '604'
        }
        expect_body = {
            'data': [{
                'type': 'reference',
                'id': Content.UUID2,
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
    def test_cli_create_solution_007(snippy, editor_data):
        """Create solution from editor.

        Create a new solution by using the prefilled default Markdown template
        in editor. The template presented in editor is manually defined in this
        test case on purpose. This tries to verity that the testing framework
        does not hide problems compared to situation where the template would
        be generated automatically by the testing framework.

        When content is created, the timestamp is allocated once for created
        and updated timestamps. The timestamp must not be updated from what
        is presented in the editor.
        """

        content = {
            'data': [
                Content.deepcopy(Solution.KAFKA_MKDN)
            ]
        }
        template = (
            '# Add brief title for content @groups',
            '',
            '> Add a description that defines the content in one chapter.',
            '',
            '> ',
            '',
            '## Description',
            '',
            '## References',
            '',
            '## Commands',
            '',
            '## Configurations',
            '',
            '## Solutions',
            '',
            '## Whiteboard',
            '',
            '## Meta',
            '',
            '> category  : solution  ',
            'created   : 2019-01-04T10:54:49.265512+00:00  ',
            'digest    : 5facdc16dc81851c2f65b112a0921eb2f2db206c7756714efb45ba0026471f11  ',
            'filename  : example-content.md  ',
            'languages : example-language  ',
            'name      : example content handle  ',
            'source    : https://www.example.com/source.md  ',
            'tags      : example,tags  ',
            'updated   : 2019-01-04T10:54:49.265512+00:00  ',
            'uuid      : a1cd5827-b6ef-4067-b5ac-3ceac07dde9f  ',
            'versions  : example=3.9.0,python>=3  ',
            ''
        )
        edited = (
            '# Testing docker log drivers @docker',
            '',
            '> Investigate docker log drivers and the logs2kafka log plugin',
            '',
            '>',
            '',
            '## Description',
            '',
            'Investigate docker log drivers.',
            '',
            '## Solutions',
            '',
            '## Whiteboard',
            '',
            '## Meta',
            '',
            '> category  : solution  ',
            'created   : 2019-01-04T10:54:49.265512+00:00  ',
            'digest    : 18473ec207798670c302fb711a40df6555e8973e26481e4cd6b2ed205f5e633c  ',
            'filename  : kubernetes-docker-log-driver-kafka.mkdn  ',
            'languages :  ',
            'name      :  ',
            'source    :  ',
            'tags      : docker,driver,kafka,kubernetes,logging,logs2kafka,moby,plugin  ',
            'updated   : 2019-01-04T10:54:49.265512+00:00  ',
            'uuid      : a1cd5827-b6ef-4067-b5ac-3ceac07dde9f  ',
            'versions  :  ',
            '')
        content['data'][0]['data'] = (
            '## Description',
            '',
            'Investigate docker log drivers.',
            '',
            '## Solutions',
            '',
            '## Whiteboard',
            ''
        )
        content['data'][0]['description'] = 'Investigate docker log drivers and the logs2kafka log plugin'
        content['data'][0]['links'] = ()
        content['data'][0]['updated'] = '2019-01-04T10:54:49.265512+00:00'
        content['data'][0]['uuid'] = Content.UUID1
        content['data'][0]['digest'] = '7941851522a23d3651f223b6d69441f77649ccb7ae1e72c6709890f2caf6401a'
        editor_data.return_value = '\n'.join(edited)
        cause = snippy.run(['snippy', 'create', '--scat', 'solution'])
        editor_data.assert_called_with('\n'.join(template))
        assert cause == Cause.ALL_OK
        Content.assert_storage(content)
Esempio n. 18
0
    def test_api_create_snippet_006(server):
        """Create one Snippet with POST.

        Send POST /snippets to create a new resource. In this case the
        request resource has only the ``data`` attribute.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data': ('docker rm $(docker ps --all -q -f status=exited)', ),
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': (),
                'links': (),
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                '2017-10-14T19:56:31.000001+00:00',
                'updated':
                '2017-10-14T19:56:31.000001+00:00',
                'uuid':
                Content.UUID1,
                'digest':
                '3d855210284302d58cf383ea25d8abdea2f7c61c4e2198da01e2c0896b0268dd'
            }]
        }
        request_body = {
            'data': [{
                'type': 'snippet',
                'attributes': {
                    'data':
                    ['docker rm $(docker ps --all -q -f status=exited)\n']
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '536'
        }
        expect_body = {
            'data': [{
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets',
            headers={'accept': 'application/json'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 19
0
    def test_api_update_snippet_002(server):
        """Update one snippet with PUT request.

        Send PUT /snippets/{id} to update existing resource with specified
        digest. Only partial set of attributes that can be modified is sent
        in request.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data':
                Snippet.REMOVE['data'],
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups':
                Snippet.REMOVE['groups'],
                'tags': (),
                'links':
                Snippet.REMOVE['links'],
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                Content.FORCED_TIME,
                'updated':
                Content.REMOVE_TIME,
                'uuid':
                '12cd5827-b6ef-4067-b5ac-3ceac07dde9f',
                'digest':
                'e56c2183edcc3a67cab99e6064439495a8af8a1d0b78bc538acd6079c841f27f'
            }]
        }
        request_body = {
            'data': {
                'type': 'snippet',
                'attributes': {
                    'data': storage['data'][0]['data'],
                    'groups': storage['data'][0]['groups'],
                    'links': storage['data'][0]['links']
                }
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '700'
        }
        expect_body = {
            'links': {
                'self':
                'http://falconframework.org/api/snippy/rest/snippets/' +
                Snippet.FORCED_UUID
            },
            'data': {
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }
        }
        result = testing.TestClient(server.server.api).simulate_put(
            path='/api/snippy/rest/snippets/53908d68425c61dc',
            headers={'accept': 'application/vnd.api+json'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 20
0
    def test_api_create_snippet_015(server):
        """Update snippet with POST that maps to PATCH.

        Send POST /snippets with the ``X-HTTP-Method-Override`` header to
        update a resource. All resource attributes are tried to be updated.
        This must generate HTTP error because it is not possible to update
        for example the ``uuid`` attribute by client.
        """

        storage = {'data': [Storage.forced]}
        request_body = {
            'data': {
                'type': 'snippet',
                'attributes': {
                    'categeory': 'solution',
                    'data': 'data row1\ndata row2',
                    'brief': 'brief description',
                    'description': 'long description',
                    'name': 'runme',
                    'groups': 'solution',
                    'tags': 'tag1,tag2',
                    'links': 'link1\nlink2',
                    'source': 'http://testing/snippets.html',
                    'versions': 'version==1.1',
                    'filename': 'filename.txt',
                    'created': 'invalid time',
                    'updated': 'invalid time',
                    'uuid': Snippet.EXITED_UUID,
                    'digest': 'invalid digest'
                }
            }
        }
        expect_headers_p3 = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '1784'
        }
        expect_headers_p2 = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '1875'
        }
        expect_body = {
            'meta':
            Content.get_api_meta(),
            'errors': [{
                'status': '400',
                'statusString': '400 Bad Request',
                'module': 'snippy.testing.testing:123',
                'title': 'json media validation failed'
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets/53908d68425c61dc',
            headers={
                'accept': 'application/vnd.api+json',
                'X-HTTP-Method-Override': 'PATCH'
            },
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_400
        assert result.headers in (expect_headers_p2, expect_headers_p3)
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 21
0
    def test_cli_update_snippet_018(snippy, edited_remove):
        """Update snippet with editor.

        Update existing text formatted snippet first in text format, then
        in Markdown format and then again in text format without making any
        changes. The content must not change when updated between different
        formats.

        Each update must generate different timestamp in content ``updated``
        attribute. In this case the updates are given from editor and the
        last update must produce the same content as the first update.

        The content in editor is explicitly defined in the test to avoid
        false positives from the test helpers that actually use the code
        itself.
        """

        edited_text = (
            '# Commented lines will be ignored.', '#',
            '# Add mandatory snippet below.',
            'docker rm --volumes $(docker ps --all --quiet)', '',
            '# Add optional brief description below.',
            'Remove all docker containers', '',
            '# Add optional description below.', '', '',
            '# Add optional name below.', '', '',
            '# Add optional comma separated list of groups below.', 'docker',
            '', '# Add optional comma separated list of tags below.',
            'cleanup,container,docker,docker-ce,moby', '',
            '# Add optional links below one link per line.',
            'https://docs.docker.com/engine/reference/commandline/rm/', '',
            '# Add optional source reference below.', '', '',
            '# Add optional comma separated list of key-value versions below.',
            '', '', '# Add optional filename below.', '')
        edited_mkdn = (
            '# Remove all docker containers again @docker', '', '> ', '',
            '> [1] https://docs.docker.com/engine/reference/commandline/rm/',
            '', '`$ docker rm --volumes $(docker ps --all --quiet)`', '',
            '## Meta', '', '> category : snippet  ',
            'created  : 2017-10-14T19:56:31.000001+00:00  ',
            'digest   : 54e41e9b52a02b631b5c65a6a053fcbabc77ccd42b02c64fdfbc76efdb18e319  ',
            'filename :  ', 'name     :  ', 'source   :  ',
            'tags     : cleanup,container,docker,docker-ce,moby  ',
            'updated  : 2017-10-14T19:56:31.000001+00:00  ',
            'uuid     : 11cd5827-b6ef-4067-b5ac-3ceac07dde9f  ',
            'versions :  ', '')

        content = {
            'data': [
                Content.deepcopy(Snippet.REMOVE),
            ]
        }
        content['data'][0]['brief'] = 'Remove all docker containers'
        content['data'][0][
            'digest'] = 'ef734194f551eaa165767fc6aa081ca0c66894fd51eef5cfbc5a26ab3e808d06'
        edited_remove.return_value = '\n'.join(edited_text)
        cause = snippy.run([
            'snippy', 'update', '--digest', '54e41e9b52a0', '--format', 'text',
            '--editor'
        ])
        assert cause == Cause.ALL_OK
        Content.assert_storage(content)

        content['data'][0]['brief'] = 'Remove all docker containers again'
        content['data'][0][
            'digest'] = 'ff16d0f4fdbe1f863e6b81189672d33d29fb436235f3a2243449aca651e8eb49'
        edited_remove.return_value = '\n'.join(edited_mkdn)
        content['data'][0]['updated'] = '2017-11-14T19:56:31.000001+00:00'
        cause = snippy.run([
            'snippy', 'update', '--digest', 'ef734194f551', '--format', 'mkdn',
            '--editor'
        ])
        assert cause == Cause.ALL_OK
        Content.assert_storage(content)

        content['data'][0]['brief'] = 'Remove all docker containers'
        content['data'][0][
            'digest'] = 'ef734194f551eaa165767fc6aa081ca0c66894fd51eef5cfbc5a26ab3e808d06'
        edited_remove.return_value = '\n'.join(edited_text)
        content['data'][0]['updated'] = '2017-12-14T19:56:31.000001+00:00'
        cause = snippy.run([
            'snippy', 'update', '--digest', 'ff16d0f4fdbe', '--format', 'text',
            '--editor'
        ])
        assert cause == Cause.ALL_OK
        Content.assert_storage(content)
Esempio n. 22
0
    def test_api_create_snippet_019(server):
        """Create and search snippet with unicode characters.

        Send POST /snippets to create a new resource. In this case resource
        contains unicode characters in string and list fields. The content must
        be also returned correctly when searching with unicode characters.
        """

        storage = {
            'data': [{
                'category':
                'snippet',
                'data': (u'Sîne klâwen durh die wolken sint geslagen',
                         u'er stîget ûf mit grôzer kraft'),
                'brief':
                u'Tagelied of Wolfram von Eschenbach Sîne klâwen',
                'description':
                u'Tagelied of Wolfram von Eschenbach Sîne klâwen',
                'name':
                '',
                'groups': (u'Düsseldorf', ),
                'tags': (u'έδωσαν', u'γλώσσα', u'ελληνική'),
                'links': (u'http://www.чухонца.edu/~fdc/utf8/', ),
                'source':
                '',
                'versions': (),
                'filename':
                '',
                'created':
                '2017-10-14T19:56:31.000001+00:00',
                'updated':
                '2017-10-14T19:56:31.000001+00:00',
                'uuid':
                Content.UUID1,
                'digest':
                'c267233096b6977ea4dd9ef41faa1559d3886ad550d8932ddb4513eae5b84fbf'
            }]
        }
        request_body = {
            'data': [{
                'type': 'snippet',
                'attributes': {
                    'data': [
                        u'Sîne klâwen durh die wolken sint geslagen',
                        u'er stîget ûf mit grôzer kraft'
                    ],
                    'brief':
                    u'Tagelied of Wolfram von Eschenbach Sîne klâwen',
                    'description':
                    u'Tagelied of Wolfram von Eschenbach Sîne klâwen',
                    'groups': [u'Düsseldorf'],
                    'tags': [u'έδωσαν', u'γλώσσα', u'ελληνική'],
                    'links': [u'http://www.чухонца.edu/~fdc/utf8/']
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '907'
        }
        expect_body = {
            'data': [{
                'type': 'snippet',
                'id': Content.UUID1,
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/snippets',
            headers={
                'accept': 'application/vnd.api+json',
                'content-type': 'application/vnd.api+json; charset=UTF-8'
            },
            body=json.dumps(request_body, ensure_ascii=False))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)

        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '967'
        }
        expect_body = {
            'meta': {
                'count': 1,
                'limit': 20,
                'offset': 0,
                'total': 1
            },
            'data': [{
                'type': 'snippet',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_get(
            path='/api/snippy/rest/snippets',
            headers={
                'accept': 'application/vnd.api+json',
                'content-type': 'application/vnd.api+json; charset=UTF-8'
            },
            query_string='sall=Düsseldorf&limit=20&sort=brief')
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
Esempio n. 23
0
    def test_api_create_solution_003(server):
        """Update Solution with POST that maps to PUT.

        Send POST /solutions/{id} to update existing resource with the
        ``X-HTTP-Method-Override`` header that overrides the operation as
        PUT. In this case the created timestamp must remain in initial
        value and the updated timestamp must be updated to reflect the
        update time.

        In this case the resource ``created`` attribute must remain in the
        initial value and the ``updated`` attribute must be set to reflect
        the update time.

        The ``uuid`` attribute must not be changed from it's initial value.

        Because the HTTP method is PUT, it overrides attributes that are
        not defined with default values. The ``filename`` attribute is set
        to empty value because of this.
        """

        storage = {'data': [Storage.dnginx]}
        storage['data'][0]['filename'] = ''
        storage['data'][0]['updated'] = Content.NGINX_TIME
        storage['data'][0]['uuid'] = Solution.BEATS_UUID
        storage['data'][0][
            'digest'] = '6d102b92af89d6bd6cb65e8d2a6e486dcff2d0fed015ba6b6afde0c99e74b9bc'
        request_body = {
            'data': {
                'type': 'solution',
                'attributes': {
                    'data': storage['data'][0]['data'],
                    'brief': storage['data'][0]['brief'],
                    'description': storage['data'][0]['description'],
                    'groups': storage['data'][0]['groups'],
                    'tags': storage['data'][0]['tags'],
                    'links': storage['data'][0]['links']
                }
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '2760'
        }
        expect_body = {
            'links': {
                'self':
                'http://falconframework.org/api/snippy/rest/solutions/' +
                Solution.BEATS_UUID
            },
            'data': {
                'type': 'solution',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/solutions/4346ba4c79247430',
            headers={
                'accept': 'application/vnd.api+json; charset=UTF-8',
                'X-HTTP-Method-Override': 'PUT'
            },
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 24
0
    def test_api_create_reference_008(server_db, used_database):
        """Try to create a Reference resource.

        Try to POST new resource when database throws an unique constraint
        violation error from the ``uuid`` attribute.

        In this case there is no stored resources and digest in generated
        error message cannot filled fromi database. The database tries to
        insert the content twice once batched and then one by one. Both of
        the inserts result same unique constraint violation.
        """

        request_body = {
            'data': [{
                'type': 'reference',
                'attributes': Request.gitlog
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '583'
        }
        expect_body = {
            'meta':
            Content.get_api_meta(),
            'errors': [{
                'status':
                '500',
                'statusString':
                '500 Internal Server Error',
                'module':
                'snippy.testing.testing:123',
                'title':
                'internal error when searching content possibly violating database unique constraints'
            }, {
                'status':
                '500',
                'statusString':
                '500 Internal Server Error',
                'module':
                'snippy.testing.testing:123',
                'title':
                'content: uuid :already exist with digest: not found'
            }]
        }
        server = server_db[0]
        db_connect = server_db[1]
        if used_database in (Helper.DB_SQLITE, Helper.DB_IN_MEMORY):
            db_connect.return_value.commit.side_effect = [
                sqlite3.IntegrityError(
                    'UNIQUE constraint failed: contents.uuid'),
                sqlite3.IntegrityError(
                    'UNIQUE constraint failed: contents.uuid')
            ]
        elif used_database == Helper.DB_POSTGRESQL:
            db_connect.return_value.commit.side_effect = [
                sqlite3.IntegrityError(
                    'duplicate key value violates unique constraint "contents_data_key"\n'
                    +
                    'DETAIL:  Key (uuid)=11cd5827-b6ef-4067-b5ac-3ceac07dde9f already exists.'
                ),
                sqlite3.IntegrityError(
                    'duplicate key value violates unique constraint "contents_data_key"\n'
                    +
                    'DETAIL:  Key (uuid)=11cd5827-b6ef-4067-b5ac-3ceac07dde9f already exists.'
                ),
            ]
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_500
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(None)
    def test_cli_create_snippet_007(snippy, capsys):
        """Create snippet with unicode characters from CLI.

        Every field that can be given from command line contains unicode
        characters. The same content must be found by searching it with
        keyword that contains unicode characters.
        """

        content = {
            'data': [{
                'category':
                'snippet',
                'data': (u'Sîne klâwen durh die wolken sint geslagen',
                         u'er stîget ûf mit grôzer kraft'),
                'brief':
                u'Tagelied of Wolfram von Eschenbach Sîne klâwen',
                'description':
                '',
                'name':
                '',
                'groups': (u'Düsseldorf', ),
                'tags': (u'έδωσαν', u'γλώσσα', u'ελληνική'),
                'links': (u'http://www.чухонца.edu/~fdc/utf8/', ),
                'source':
                '',
                'versions': (),
                'languages': (),
                'filename':
                '',
                'created':
                Content.REMOVE_TIME,
                'updated':
                Content.REMOVE_TIME,
                'uuid':
                Content.UUID1,
                'digest':
                'a74d83df95d5729aceffc472433fea4d5e3fd2d87b510112fac264c741f20438'
            }]
        }
        data = Const.DELIMITER_DATA.join(content['data'][0]['data'])
        brief = content['data'][0]['brief']
        groups = Const.DELIMITER_GROUPS.join(content['data'][0]['groups'])
        tags = Const.DELIMITER_TAGS.join(content['data'][0]['tags'])
        links = Const.DELIMITER_LINKS.join(content['data'][0]['links'])
        cause = snippy.run(['snippy', 'create', '--content', data, '--brief', brief, '--groups', groups, '--tags', tags, '--links', links])  # pylint: disable=line-too-long
        assert cause == Cause.ALL_OK
        Content.assert_storage(content)

        output = (
            u'1. Tagelied of Wolfram von Eschenbach Sîne klâwen @Düsseldorf [a74d83df95d5729a]',
            u'', u'   $ Sîne klâwen durh die wolken sint geslagen',
            u'   $ er stîget ûf mit grôzer kraft', u'',
            u'   # έδωσαν,γλώσσα,ελληνική',
            u'   > http://www.чухонца.edu/~fdc/utf8/', u'', u'OK', u'')
        out, err = capsys.readouterr()
        cause = snippy.run(
            ['snippy', 'search', '--sall', 'klâwen', '--no-ansi'])
        out, err = capsys.readouterr()
        assert cause == Cause.ALL_OK
        assert out == Const.NEWLINE.join(output)
        assert not err
Esempio n. 26
0
    def test_api_create_reference_010(server):
        """Create one Reference resource.

        Send POST /references to create a new resource. In this case every
        attribute has additional leading and trailing whitespaces that must
        be trimmed when stored.
        """

        storage = {
            'data': [{
                'category':
                'reference',
                'data': (),
                'brief':
                'short brief',
                'description':
                'longer description',
                'name':
                'short name',
                'groups': ('python', ),
                'tags': ('spaces', 'tabs'),
                'links': ('link1', 'link2'),
                'source':
                'short source link',
                'versions': ('kafka==1.0.0', ),
                'languages': ('python', ),
                'filename':
                'shortfilename.yaml',
                'created':
                Content.REGEXP_TIME,
                'updated':
                Content.REGEXP_TIME,
                'uuid':
                Content.UUID1,
                'digest':
                'f68078e62794f6e1e00ccff301fb83ea01b7587959d6ab7b444c18b637f6e61b'
            }]
        }
        request_body = {
            'data': [{
                'type': 'reference',
                'attributes': {
                    'data': ['     first row   ', '   second row  '],
                    'brief': ' short brief  ',
                    'description': ' longer description  ',
                    'name': '  short name   ',
                    'groups': [
                        '    python   ',
                    ],
                    'tags': ['  spaces   ', '  tabs    '],
                    'links': ['  link1  ', '    link2   '],
                    'source': '  short source link   ',
                    'versions': ['  kafka==1.0.0   '],
                    'languages': ['  python   '],
                    'filename': '  shortfilename.yaml   '
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '634'
        }
        expect_body = {
            'data': [{
                'type': 'reference',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 27
0
    def test_api_update_reference_009(server):
        """Update reference with PUT request.

        Send PUT /references/{id} to replace existing resource with digest.
        The PUT sets all but the mandatory ``links`` attribute to empty values.
        """

        storage = {'data': [Storage.gitlog]}
        storage['data'][0]['brief'] = ''
        storage['data'][0]['description'] = ''
        storage['data'][0]['name'] = ''
        storage['data'][0]['groups'] = ()
        storage['data'][0]['tags'] = ()
        storage['data'][0]['source'] = ''
        storage['data'][0]['versions'] = ()
        storage['data'][0]['languages'] = ()
        storage['data'][0]['filename'] = ''
        storage['data'][0]['created'] = Content.GITLOG_TIME
        storage['data'][0]['updated'] = Content.PYTEST_TIME
        storage['data'][0][
            'digest'] = '54c493ade0f808e3d1b16bb606484a51bb0f7eb9c0592c46aea5196bd891881c'
        request_body = {
            'data': {
                'type': 'reference',
                'attributes': {
                    'links': storage['data'][0]['links'],
                    'brief': '',
                    'description': '',
                    'name': '',
                    'groups': (),
                    'tags': (),
                    'source': '',
                    'versions': (),
                    'languages': (),
                    'filename': ''
                }
            }
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '651'
        }
        expect_body = {
            'links': {
                'self':
                'http://falconframework.org/api/snippy/rest/references/' +
                Reference.GITLOG_UUID
            },
            'data': {
                'type': 'reference',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }
        }
        result = testing.TestClient(server.server.api).simulate_put(
            path='/api/snippy/rest/references/5c2071094dbfaa33',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_200
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 28
0
    def test_api_create_reference_011(server):
        """Create one Reference resource.

        Send POST /references to create a new resource. In this case only
        the mandatory ``links`` attribute for Reference resource is defined.
        """

        storage = {
            'data': [{
                'category':
                'reference',
                'data': (),
                'brief':
                '',
                'description':
                '',
                'name':
                '',
                'groups': ('default', ),
                'tags': (),
                'links': ('link1', 'link2'),
                'source':
                '',
                'versions': (),
                'languages': (),
                'filename':
                '',
                'created':
                Content.REGEXP_TIME,
                'updated':
                Content.REGEXP_TIME,
                'uuid':
                Content.UUID1,
                'digest':
                'b978df98e539644f9861a13803c19345d286544302ccedfd98c36cf16724eb80'
            }]
        }
        request_body = {
            'data': [{
                'type': 'reference',
                'attributes': {
                    'links': ['link1', 'link2'],
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '523'
        }
        expect_body = {
            'data': [{
                'type': 'reference',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={'accept': 'application/vnd.api+json; charset=UTF-8'},
            body=json.dumps(request_body))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)
Esempio n. 29
0
    def teardown_class(cls):
        """Teardown class."""

        Content.delete()
Esempio n. 30
0
    def test_api_create_reference_012(server):
        """Create new reference with duplicated content field values.

        Send POST /references to create a new resource. In this case the
        resource attributes contain duplicated values. For example, there is
        a tag 'python' included twice in the ``tags`` attribute. Only unique
        values in attributes in array context must be added.

        Links are not sorted because the order is assumed to convey relevant
        information related to link importance in case of Reference resource.
        Because of this, removal of duplicated values in ``links`` attribute
        must not change the order which links are added.
        """

        storage = {
            'data': [{
                'category':
                'reference',
                'data': (),
                'brief':
                'short brief',
                'description':
                '',
                'name':
                '',
                'groups': ('docker', 'python'),
                'tags': ('pypy', 'swarm'),
                'links':
                ('http://www.dot.com/link2', 'http://www.dot.com/link1'),
                'source':
                '',
                'versions': (),
                'languages': (),
                'filename':
                '',
                'created':
                '2018-06-22T13:11:13.678729+00:00',
                'updated':
                '2018-06-22T13:11:13.678729+00:00',
                'uuid':
                Content.UUID1,
                'digest':
                'aa6aa8c9a94f1959c9935d7bc6aca060edd5369ae5a24d26ce2960852751d09d'
            }]
        }
        request_body = {
            'data': [{
                'type': 'reference',
                'attributes': {
                    'brief':
                    'short brief',
                    'description':
                    '',
                    'groups': ['docker', 'docker', 'python'],
                    'tags': ['swarm', 'swarm', 'pypy'],
                    'links': [
                        'http://www.dot.com/link2', 'http://www.dot.com/link2',
                        'http://www.dot.com/link1'
                    ],
                    'versions': [],
                    'languages': []
                }
            }]
        }
        expect_headers = {
            'content-type': 'application/vnd.api+json; charset=UTF-8',
            'content-length': '596'
        }
        expect_body = {
            'data': [{
                'type': 'reference',
                'id': storage['data'][0]['uuid'],
                'attributes': storage['data'][0]
            }]
        }
        result = testing.TestClient(server.server.api).simulate_post(
            path='/api/snippy/rest/references',
            headers={
                'accept': 'application/vnd.api+json',
                'content-type': 'application/vnd.api+json; charset=UTF-8'
            },
            body=json.dumps(request_body, ensure_ascii=False))
        assert result.status == falcon.HTTP_201
        assert result.headers == expect_headers
        Content.assert_restapi(result.json, expect_body)
        Content.assert_storage(storage)