Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Communications Backbone System
backbone-message-format
Commits
714a573a
Commit
714a573a
authored
8 months ago
by
Dan Jones
Browse files
Options
Download
Plain Diff
Merge branch 'release-v1-0-0' into 'master'
Release v1 0 0 See merge request
!35
parents
b34b33b0
a73890ff
dev
76-should-depth-and-altitude-be-coordinates
80-add-informational-type-primitive
87-remove-comment-for-platform-status-state
87-remove-todo-comment-from-platform-state
action-refactor-test
master
v2.0.0
v2.0.0-beta.11
v2.0.0-beta.10
v2.0.0-beta.9
v2.0.0-beta.8
v2.0.0-beta.7
v2.0.0-beta.6
v2.0.0-beta.5
v2.0.0-beta.4
v2.0.0-beta.3
v2.0.0-beta.2
v2.0.0-beta.1
v1.0.0
1 merge request
!35
Release v1 0 0
Pipeline
#230732
passed with stages
in 1 minute and 3 seconds
Changes
12
Pipelines
5
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1328 additions
and
1139 deletions
+1328
-1139
.gitignore
.gitignore
+1
-0
.gitlab-ci.yml
.gitlab-ci.yml
+1
-0
CHANGELOG.md
CHANGELOG.md
+13
-1
README.md
README.md
+14
-8
docker/docker-compose-test.yaml
docker/docker-compose-test.yaml
+1
-1
generate_schema_config.py
generate_schema_config.py
+130
-8
gitlab/test-js.yml
gitlab/test-js.yml
+13
-0
project/soar/swagger.json
project/soar/swagger.json
+1108
-1108
setup.py
setup.py
+1
-1
tests-js/docker/Dockerfile
tests-js/docker/Dockerfile
+10
-1
tests-js/soar-examples.test.js
tests-js/soar-examples.test.js
+1
-1
tests/test_schemas.py
tests/test_schemas.py
+35
-10
No files found.
.gitignore
View file @
714a573a
__pycache__/
*.pyc
tests/test_swagger.json
\ No newline at end of file
This diff is collapsed.
Click to expand it.
.gitlab-ci.yml
View file @
714a573a
...
...
@@ -2,6 +2,7 @@ include:
-
project
:
communications-backbone-system/backbone-infrastructure-config
ref
:
master
file
:
gitlab/all.yml
-
local
:
/gitlab/test-js.yml
variables
:
DOCKER_IMAGE_NAME
:
backbone-message-format
...
...
This diff is collapsed.
Click to expand it.
CHANGELOG.md
View file @
714a573a
...
...
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
## [v1.0.0] - 2024-08-28
### Changed
-
Use discover to find all unit tests
-
Run tests against current format definitions
-
Test that formats match saved schema
-
Run python and javascript tests in CI
-
Refactor schema script to remove invalid definitions object automatically
-
Refactor generate_schema_config script to output file on -f flag
## [v0.2.0] - 2024-02-06
### Added
...
...
@@ -35,6 +46,7 @@ JSON schema definitions for the SoAR project
Example messages matching the schema for each partner
[
unreleased
]:
https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/compare/v0.2.0...dev
[
unreleased
]:
https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/compare/v1.0.0...dev
[
v1.0.0
]:
https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/compare/v0.2.0...v1.0.0
[
v0.2.0
]:
https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/compare/v0.1.0...v0.2.0
[
v0.1.0
]:
https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/compare/9e6ce245...v0.1.0
This diff is collapsed.
Click to expand it.
README.md
View file @
714a573a
...
...
@@ -72,22 +72,28 @@ eg
## Run Docs & Save Schema When Updating Message Formats
1.
Run the command below and go to
`http://127.0.0.1:5000`
```
python3 generate_schema_config.py
python3 generate_schema_config.py
-f
```
2.
Copy the schema generated
`http://127.0.0.1:5000/soar_protocol.json`
into the
`backbone-message-format/project/<project_name>/swagger.json`
3.
In the json copied, remove the key
`"definitions"`
from the schema and save this.
2.
Commit any changes to the
`backbone-message-format/project/<project_name>/swagger.json`
## Run Tests
We have found slightly different behaviour between the OpenAPI validators in python and javascript.
By running tests in both languages we should protect against messages that pass validation in
one client but fail in another.
Run both tests below:
1.
Test 1
1.
Test 1 - Use python validators
```
python3 -m unittest
tests/test_schemas.py
python3 -m unittest
discover
```
2.
Test 2
2.
Test 2
- Use javascript validators
```
cd tests-js/docker; docker compose up --build
# Compile schema and run javascript validation tests in docker
python3 test-js.py
```
## Quick Links
...
...
This diff is collapsed.
Click to expand it.
docker/docker-compose-test.yaml
View file @
714a573a
...
...
@@ -12,4 +12,4 @@ services:
-
PYTHONDONTWRITEBYTECODE=1
volumes
:
-
../:/app
command
:
"
python3
-m
unittest
tests/test_schemas.py"
\ No newline at end of file
command
:
"
python3
-m
unittest
discover"
This diff is collapsed.
Click to expand it.
generate_schema_config.py
View file @
714a573a
...
...
@@ -14,11 +14,19 @@ from formats.alert import alert_schema
from
flasgger
import
Swagger
from
flask
import
Flask
import
argparse
import
json
import
os
app
=
Flask
(
__name__
)
url_prefix
=
os
.
getenv
(
"URL_PREFIX"
,
""
)
# Enable running on domain sub-path
URL_PREFIX
=
os
.
getenv
(
"URL_PREFIX"
,
""
)
# Allow env override of default host
FLASK_HOST
=
os
.
getenv
(
"FLASK_HOST"
,
"localhost"
)
# Allow env override of default port
FLASK_PORT
=
os
.
getenv
(
"FLASK_PORT"
,
5000
)
# Switch on debug mode if env var is truthy
FLASK_DEBUG
=
os
.
getenv
(
"FLASK_DEBUG"
,
"False"
).
lower
()
in
(
"true"
,
"1"
,
"t"
)
swagger_config
=
{
"openapi"
:
"3.0.2"
,
...
...
@@ -35,7 +43,7 @@ swagger_config = {
"route"
:
"/soar_protocol.json"
,
}
],
"url_prefix"
:
url_prefix
,
"url_prefix"
:
URL_PREFIX
,
"paths"
:
{},
"components"
:
{
"schemas"
:
{
...
...
@@ -103,11 +111,125 @@ swagger_config = {
},
}
swag
=
Swagger
(
app
,
config
=
swagger_config
,
merge
=
True
)
flask_host
=
os
.
getenv
(
"FLASK_HOST"
,
"localhost"
)
# Sets to whatever FLASK_HOST is, or defaults to localhost
def
configure_flask
(
swagger_config
):
"""
Setup a flask app, load flasgger
and then patch to remove invalid
definitions:{} object
"""
app
=
Flask
(
__name__
)
Swagger
(
app
,
config
=
swagger_config
,
merge
=
True
)
# Replace schema route to remove invalid
# definitions: {}
# Should be fixed if Flassger 0.9.7 is released
#
# The last release of flasgger was Aug 2020
# This bug was fixed in Nov 2021
# There is a pre-release from May 2023
# Until the fix gets released we have to
# remove the invalid definitions object
# from the spec
@
app
.
after_request
def
after_request_decorator
(
response
):
"""
I didn't want to mess with flasgger so
this blunt workaround that runs on every
route and then checks whether it's required
"""
is_response
=
type
(
response
).
__name__
==
"Response"
is_json
=
is_response
and
response
.
content_type
==
"application/json"
if
is_json
:
parsed
=
response
.
json
if
"definitions"
in
parsed
:
del
parsed
[
"definitions"
]
response
.
data
=
json
.
dumps
(
parsed
)
return
response
return
app
def
serve
(
swagger_config
):
"""
Run as local flask app on FLASK_PORT|5000
"""
app
=
configure_flask
(
swagger_config
)
app
.
run
(
debug
=
FLASK_DEBUG
,
host
=
FLASK_HOST
,
port
=
FLASK_PORT
)
def
compile_schema
(
swagger_config
):
"""Extract the output schema from flasgger
The only way I have found to do this is to
use a test client to make the GET request
for the page
The function that returns the definition
can't be called outside the flask app context
"""
app
=
configure_flask
(
swagger_config
)
route
=
swagger_config
[
"specs"
][
0
][
"route"
]
client
=
app
.
test_client
()
response
=
client
.
get
(
route
)
spec
=
response
.
json
return
spec
def
write_schema
(
swagger_config
,
file_path
):
"""
Dump schema to specified file
"""
spec
=
compile_schema
(
swagger_config
)
json_schema
=
json
.
dumps
(
spec
,
indent
=
2
)
with
open
(
file_path
,
"w"
)
as
f
:
f
.
write
(
json_schema
)
def
get_options
():
"""
Parse script arguments
"""
parser
=
argparse
.
ArgumentParser
(
description
=
"Generate the schema"
,
formatter_class
=
argparse
.
ArgumentDefaultsHelpFormatter
,
)
parser
.
add_argument
(
"-s"
,
"--serve"
,
dest
=
"run_flask"
,
action
=
"store_true"
,
help
=
"Run flask app"
,
default
=
False
,
)
parser
.
add_argument
(
"-f"
,
"--file"
,
dest
=
"output_file"
,
action
=
"store_true"
,
help
=
"Save output to schema file"
,
default
=
False
,
)
parser
.
add_argument
(
"filename"
,
nargs
=
"?"
,
default
=
"project/soar/swagger.json"
)
args
=
parser
.
parse_args
()
config
=
vars
(
args
)
# If no flag is specified default to running the flask server
if
all
(
v
is
False
for
v
in
config
.
values
()):
config
[
"run_flask"
]
=
True
return
config
if
__name__
==
"__main__"
:
app
.
run
(
debug
=
False
,
host
=
flask_host
)
# Parse script args
config
=
get_options
()
# Output compiled schema
if
config
.
get
(
"output_file"
):
write_schema
(
swagger_config
,
config
.
get
(
"filename"
))
# Run flask app
if
config
.
get
(
"run_flask"
):
serve
(
swagger_config
)
This diff is collapsed.
Click to expand it.
gitlab/test-js.yml
0 → 100644
View file @
714a573a
test-js
:
stage
:
test
script
:
-
cd tests-js/docker
-
docker compose up --build
tags
:
-
shell
rules
:
-
if
:
'
$CI_SKIP_TESTS
==
"1"'
when
:
never
-
if
:
'
$CI_IGNORE_TESTS
==
"1"'
allow_failure
:
true
-
when
:
on_success
This diff is collapsed.
Click to expand it.
project/soar/swagger.json
View file @
714a573a
...
...
@@ -1150,10 +1150,10 @@
}
}
},
"info"
:{
"description"
:
"SoAR message protocol in schemas"
,
"title"
:
"SoAR Backbone Message Formats"
,
"version"
:
"0.2
"
"info"
:
{
"description"
:
"SoAR message protocol in schemas"
,
"title"
:
"SoAR Backbone Message Formats"
,
"version"
:
"1.0
"
},
"openapi"
:
"3.0.2"
,
"paths"
:
{}
...
...
This diff is collapsed.
Click to expand it.
setup.py
View file @
714a573a
...
...
@@ -2,7 +2,7 @@ from setuptools import setup
setup
(
version
=
"
0.2
.0"
,
version
=
"
1.0
.0"
,
name
=
"backbone_message_format"
,
python_requires
=
">=3.8"
,
packages
=
[
"backbone_formats"
,
"soar_schema"
],
...
...
This diff is collapsed.
Click to expand it.
tests-js/docker/Dockerfile
View file @
714a573a
FROM
node:18.7.0-alpine
FROM
python:3.9.16-alpine
# Add node for running JS validator tests
RUN
apk add
--update
nodejs npm
WORKDIR
/app/tests-js
COPY
tests-js/package.json /app/tests-js/package.json
RUN
npm
install
-g
yarn
RUN
yarn
install
WORKDIR
/app
COPY
. /app
# compile test schema from message
RUN
pip
install
-r
requirements.txt
RUN
python generate_schema_config.py
-f
tests/test_swagger.json
WORKDIR
/app/tests-js
CMD
[ 'yarn', 'test' ]
This diff is collapsed.
Click to expand it.
tests-js/soar-examples.test.js
View file @
714a573a
...
...
@@ -3,7 +3,7 @@ const Validator = require('swagger-model-validator');
const
OpenAPISchemaValidator
=
require
(
'
openapi-schema-validator
'
).
default
;
const
getSchema
=
()
=>
{
const
schema
=
require
(
`
${
__dirname
}
/../
project/soar/
swagger.json`
);
const
schema
=
require
(
`
${
__dirname
}
/../
tests/test_
swagger.json`
);
return
schema
;
};
...
...
This diff is collapsed.
Click to expand it.
tests/test_schemas.py
View file @
714a573a
...
...
@@ -5,12 +5,28 @@ from jsonschema.validators import RefResolver
import
unittest
import
json
import
os
from
generate_schema_config
import
write_schema
,
swagger_config
SCHEMA_DIR
=
"project/soar/swagger.json"
MOCK_DATA_DIR
=
"examples/"
class
SchemaTestCase
(
unittest
.
TestCase
):
def
load_schema
(
self
,
file_path
=
None
):
if
file_path
:
schema_path
=
file_path
else
:
schema_path
=
os
.
getenv
(
"SCHEMA_PATH"
)
schema
,
_
=
read_from_filename
(
schema_path
)
return
schema
@
classmethod
def
setUpClass
(
cls
):
test_schema_path
=
"tests/test_swagger.json"
os
.
environ
[
"SCHEMA_PATH"
]
=
test_schema_path
write_schema
(
swagger_config
,
test_schema_path
)
class
SchemaError
(
Exception
):
"""
Test config specs of swagger.json for projects
...
...
@@ -19,26 +35,37 @@ class SchemaError(Exception):
def
__init__
(
self
,
exception_type
,
message
):
self
.
type
=
exception_type
self
.
message
=
message
super
().
__init__
(
self
.
message
)
super
().
__init__
(
message
)
class
TestSpecs
(
unittest
.
TestCase
):
class
TestCompiledSoarSpec
(
SchemaTestCase
):
"""
Test the saved version of the compiled schema has been updated
"""
def
test_compiled_spec_matches_definitions
(
self
):
print
(
"TEST: definitions match project/soar/swagger.json"
)
derived_schema
=
self
.
load_schema
()
saved_schema
=
self
.
load_schema
(
"project/soar/swagger.json"
)
self
.
assertEqual
(
saved_schema
,
derived_schema
)
class
TestSpecs
(
SchemaTestCase
):
def
test_swagger_specs
(
self
):
"""
Test specs (swagger.json generated from generate_schema_config.py)
"""
schema
,
spec_url
=
read_from_filename
(
"tests/fixtures/swagger.json"
)
print
(
"TEST: compiled schema matches openapi v3 spec"
)
schema
=
self
.
load_schema
()
self
.
assertIsNone
(
openapi_v30_spec_validator
.
validate
(
schema
))
class
TestAllMessageExamples
(
unittest
.
TestCase
):
class
TestAllMessageExamples
(
Schema
TestCase
):
def
test_schema_specs
(
self
):
"""
Test specs (swagger.json generated from generate_schema_config.py)
"""
schema_ref
=
open
(
SCHEMA_DIR
)
schema
=
json
.
load
(
schema_ref
)
schema_ref
.
close
()
schema
=
self
.
load_schema
()
partner_dir_list
=
os
.
listdir
(
MOCK_DATA_DIR
)
...
...
@@ -70,8 +97,6 @@ class TestAllMessageExamples(unittest.TestCase):
f
.
close
()
print
(
"Done."
)
schema_ref
.
close
()
if
__name__
==
"__main__"
:
unittest
.
main
()
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment