Skip to content

Commit 427921b

Browse files
authored
create integration test folder (#222)
Automation code base for functional testing Added more tests and functions for testing framework Set up execute_tests job for circleci workflow Update .gitignore Update config.yml Update default.ini
1 parent 4e1e520 commit 427921b

File tree

15 files changed

+495
-17
lines changed

15 files changed

+495
-17
lines changed

.circleci/config.yml

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
name: Builder
1616
command: make build
1717
- run:
18-
name: Run tests
18+
name: Run unit tests
1919
command: |
2020
make testall
2121
cp splunk-firehose-nozzle /tmp
@@ -44,13 +44,6 @@ jobs:
4444
.circleci/update_manifest.sh
4545
.circleci/pre-req.sh
4646
cf push -f .circleci/ci_nozzle_manifest.yml -u process --random-route
47-
- run:
48-
name: Teardown deployment env
49-
command: |
50-
sleep 10
51-
echo "Teardown deployment env"
52-
cf delete splunk-firehose-nozzle -f
53-
cf delete-org splunk-ci -f
5447
5548
tile-builder:
5649
docker:
@@ -71,6 +64,60 @@ jobs:
7164
cp -R /tmp/splunk-firehose-nozzle .
7265
.circleci/push_tile.sh
7366
67+
execute_tests:
68+
docker:
69+
- image: circleci/golang:1.12
70+
working_directory: /go/src/github.com/cloudfoundry-community/splunk-firehose-nozzle
71+
steps:
72+
- attach_workspace:
73+
at: /tmp
74+
- checkout
75+
- run:
76+
name: Install dependencies
77+
command: |
78+
curl https://glide.sh/get | sh
79+
go get -t ./...
80+
cp -R /tmp/splunk-firehose-nozzle .
81+
- run:
82+
name: Deploy data-gen
83+
command: |
84+
.circleci/pre-req.sh
85+
cf push -f .circleci/data_gen_manifest.yml -u process -p tools/data_gen --random-route
86+
sleep 10
87+
- run:
88+
name: Prepare test environment
89+
command: |
90+
.circleci/pre-functional-test.sh
91+
- run:
92+
name: Executing tests
93+
command: |
94+
.circleci/functional-test.sh
95+
96+
teardown:
97+
docker:
98+
- image: circleci/golang:1.12
99+
working_directory: /go/src/github.com/cloudfoundry-community/splunk-firehose-nozzle
100+
steps:
101+
- attach_workspace:
102+
at: /tmp
103+
- checkout
104+
- run:
105+
name: Install dependencies
106+
command: |
107+
curl https://glide.sh/get | sh
108+
go get -t ./...
109+
cp -R /tmp/splunk-firehose-nozzle .
110+
.circleci/pre-req.sh
111+
- run:
112+
name: Teardown
113+
command: |
114+
echo "Teardown deployment env"
115+
cf delete splunk-firehose-nozzle -f
116+
cf delete data_gen -f
117+
cf delete-org splunk-ci-org -f
118+
when:
119+
always
120+
74121
workflows:
75122
version: 2
76123
build-and-deploy-nozzle:
@@ -89,4 +136,23 @@ workflows:
89136
- deploy-nozzle
90137
filters:
91138
branches:
92-
only: master
139+
only: master
140+
- execute_tests:
141+
requires:
142+
- build
143+
- deploy-nozzle
144+
filters:
145+
branches:
146+
only:
147+
- develop
148+
- master
149+
- teardown:
150+
requires:
151+
- build
152+
- deploy-nozzle
153+
- execute_tests
154+
filters:
155+
branches:
156+
only:
157+
- develop
158+
- master

.circleci/functional-test.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
cd testing/integration
4+
. venv/bin/activate
5+
pytest --durations=10

.circleci/pre-functional-test.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
3+
sudo apt-get install python3.7
4+
sudo apt-get install python3-pip
5+
cd testing/integration
6+
pip3 install virtualenv
7+
virtualenv venv
8+
source venv/bin/activate
9+
pip3 install -r requirements.txt

.circleci/pre-req.sh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ sudo apt-get install cf-cli
1212
#CF Login
1313
cf login --skip-ssl-validation -a $API_ENDPOINT -u $API_USER -p $API_PASSWORD -o system -s system
1414
#Create splunk-ci org and space
15-
if [ "`cf o | grep "splunk-ci"`" == "splunk-ci" ]; then
16-
echo "splunk-ci org already exists"
17-
cf target -o "splunk-ci" -s "splunk-ci"
15+
if [ "`cf o | grep "splunk-ci-org"`" == "splunk-ci-org" ]; then
16+
echo "splunk-ci-org org already exists"
17+
cf target -o "splunk-ci-org" -s "splunk-ci-space"
1818
else
19-
echo "creating splunk-ci org and space"
20-
cf create-org splunk-ci
21-
cf target -o splunk-ci
22-
cf create-space splunk-ci
23-
cf target -o "splunk-ci" -s "splunk-ci"
19+
echo "creating splunk-ci-org org and space"
20+
cf create-org splunk-ci-org
21+
cf target -o splunk-ci-org
22+
cf create-space splunk-ci-space
23+
cf target -o "splunk-ci-org" -s "splunk-ci-space"
2424
fi

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ data_gen
1414
manifest*.yml
1515
splunk-firehose-nozzle.iml
1616
vendor/github.com/cloudfoundry/sonde-go/definitions/
17+
testing/integration/venv/
18+
testing/integration/config/local.ini
19+
*.pyc

testing/integration/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## PCL Integration Tests Environment Setup
2+
3+
## Using remote environment
4+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[DEFAULT]
2+
splunk_url =
3+
splunk_user =
4+
splunk_password =
5+
go_package_name = main
6+
api_endpoint =
7+
client_id =
8+
client_secret =
9+
splunk_host =
10+
splunk_token =
11+
splunk_index =
12+
job_name = splunk-nozzle
13+
add_app_info = true
14+
bolted_path = cache.db
15+
events = ValueMetric,CounterEvent,Error,LogMessage,HttpStartStop,ContainerMetric
16+
extra_fields = name:update-ci-test
17+
subscription_id = splunk-ci
18+
enable_event_tracing = true
19+
20+
max_retries = 5
21+
22+
23+
24+
25+

testing/integration/conftest.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import logging
2+
import logging.config
3+
import os
4+
import sys
5+
import pytest
6+
import configparser
7+
from os.path import join
8+
9+
10+
from lib.helper import get_config_folder, get_project_folder
11+
12+
_current_dir = os.path.dirname(os.path.realpath(__file__))
13+
sys.path.insert(0, get_project_folder())
14+
15+
16+
@pytest.fixture(scope="session", autouse=True)
17+
def setup_logging():
18+
logging.config.fileConfig(os.path.join(_current_dir, "logging.conf"))
19+
20+
21+
@pytest.fixture(scope="session", autouse=True)
22+
def nozzle_logger(setup_logging):
23+
return logging.getLogger("nozzle")
24+
25+
26+
@pytest.fixture(scope="session", autouse=True)
27+
def splunk_logger(setup_logging):
28+
return logging.getLogger("splunk")
29+
30+
31+
def pytest_addoption(parser):
32+
"""
33+
This function is sued to add command line parameters to test suite
34+
"""
35+
env_var = os.environ
36+
parser.addoption("--splunk-url", help="splunk url used to send test data to.",
37+
default=env_var.get('SPLUNK_URL'))
38+
parser.addoption("--splunk-user", help="splunk username",
39+
default=env_var.get('SPLUNK_USER'))
40+
parser.addoption("--splunk-password", help="splunk user password",
41+
default=env_var.get('SPLUNK_PASSWORD'))
42+
parser.addoption("--api-endpoint", help="pleasanton cf api endpoint.",
43+
default=env_var.get('API_ENDPOINT'))
44+
parser.addoption("--splunk-index", help="splunk index on hec setting.",
45+
default=env_var.get('SPLUNK_INDEX'))
46+
47+
48+
@pytest.fixture(scope="class")
49+
def test_env(request):
50+
"""
51+
provides the config dict based on default and local properties
52+
53+
local properties over ride default properties. sensitive information should
54+
be placed in ``config/local.ini`` and this file should not be version
55+
controlled.
56+
"""
57+
config_folder = get_config_folder()
58+
parser = configparser.ConfigParser()
59+
60+
if os.path.exists(join(config_folder, 'local.ini')):
61+
parser.read([join(config_folder, 'config.ini'),
62+
join(config_folder, 'local.ini')])
63+
else:
64+
parser.read(join(config_folder, 'config.ini'))
65+
66+
cfg = parser.items('DEFAULT')
67+
conf = dict(cfg)
68+
69+
conf["splunk_url"] = request.config.getoption("--splunk-url")
70+
conf["splunk_user"] = request.config.getoption("--splunk-user")
71+
conf["splunk_password"] = request.config.getoption("--splunk-password")
72+
conf["api_endpoint"] = request.config.getoption("--api-endpoint")
73+
conf["splunk_index"] = request.config.getoption("--splunk-index")
74+
75+
return conf

testing/integration/lib/helper.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Common functions used in this project
2+
3+
import os
4+
5+
6+
def get_project_folder():
7+
"""
8+
returns the project root folder
9+
"""
10+
return os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
11+
12+
13+
def get_config_folder():
14+
"""
15+
returns the config folder
16+
"""
17+
return os.path.join(get_project_folder(), "config")
18+
19+
20+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from itertools import zip_longest
2+
from json_delta import udiff
3+
4+
from functools import partial
5+
import json
6+
dumps = partial(json.dumps, ensure_ascii=False, indent=2)
7+
8+
9+
def assert_json_contains(expected, actual, msg="JSON mismatch"):
10+
"""
11+
This method asserts that `expected` is a subset of `actual`
12+
parameters:
13+
@expected:
14+
@actual:
15+
@msg:
16+
"""
17+
__tracebackhide__ = True
18+
19+
subset = _extract_subset(actual, expected)
20+
if subset != expected:
21+
diff = '\n'.join(udiff(expected, subset, indent=2))
22+
raise AssertionError("{msg}:\n{diff}".format(msg=msg, diff=diff))
23+
24+
25+
def _extract_subset(source, mask):
26+
if isinstance(mask, dict) and isinstance(source, dict):
27+
return _extract_dict_subset(source, mask)
28+
elif isinstance(mask, list) and isinstance(source, list):
29+
return _extract_list_subset(source, mask)
30+
else:
31+
return source
32+
33+
34+
def _extract_dict_subset(source, mask):
35+
target = {}
36+
for key in mask:
37+
if key in source:
38+
target[key] = _extract_subset(source[key], mask[key])
39+
return target
40+
41+
42+
MISSING = object()
43+
def _extract_list_subset(source, mask):
44+
target = []
45+
for source_item, mask_item in zip_longest(source, mask, fillvalue=MISSING):
46+
if mask_item is MISSING:
47+
target.append(source_item)
48+
elif source_item is not MISSING:
49+
target.append(_extract_subset(source_item, mask_item))
50+
return target

0 commit comments

Comments
 (0)