Commit fd86e47b authored by Pid's avatar Pid Committed by GitHub

Merge branch 'master' into add_label_schema_0

parents 678a3596 0863fe59
......@@ -7,14 +7,14 @@ jdk:
install: true
env:
- GROUP=weaveworksdemos COMMIT=$TRAVIS_COMMIT TAG=$TRAVIS_TAG;
- GROUP=weaveworksdemos COMMIT=$TRAVIS_COMMIT TAG=$TRAVIS_TAG REPO=cart;
script:
- set -e
- ./scripts/build.sh;
- travis_wait ./scripts/build.sh;
- ./test/test.sh unit.py
- ./test/test.sh component.py
# - ./test/test.sh container.py --tag $TAG
- ./test/test.sh container.py --tag $TAG
after_success:
- set -e;
......@@ -25,3 +25,20 @@ after_success:
fi;
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS;
- ./scripts/push.sh
before_install:
- openssl aes-256-cbc -K $encrypted_71d9c8a3a58a_key -iv $encrypted_71d9c8a3a58a_iv
-in cart_deploy_rsa.enc -out cart_deploy_rsa -d
before_deploy:
- eval "$(ssh-agent -s)"
- chmod 600 $TRAVIS_BUILD_DIR/${REPO}_deploy_rsa
- ssh-add $TRAVIS_BUILD_DIR/${REPO}_deploy_rsa
addons:
ssh_known_hosts: $BASTION
deploy:
provider: script
skip_cleanup: true
# The deploy.sh file actually points to the deploy file on the bastion. Not one in the repo.
script: ssh -o StrictHostKeyChecking=no $BASTION_USER@$BASTION ./deploy.sh ${REPO} $COMMIT
on:
branch: master
[![Build Status](https://travis-ci.org/microservices-demo/carts.svg?branch=master)](https://travis-ci.org/microservices-demo/carts) [![Coverage Status](https://coveralls.io/repos/github/microservices-demo/carts/badge.svg?branch=master)](https://coveralls.io/github/microservices-demo/carts?branch=master)
[![](https://images.microbadger.com/badges/image/weaveworksdemos/cart.svg)](http://microbadger.com/images/weaveworksdemos/cart "Get your own image badge on microbadger.com")
# cart
A microservices-demo service that provides shopping carts for users.
......
{
"swagger": "2.0",
"info": {
"version": "",
"title": "Carts and items",
"description": "Carts and items resources",
"license": {
"name": "MIT",
"url": "http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT"
}
},
"host": "carts",
"basePath": "/",
"securityDefinitions": {},
"schemes": [
"http"
],
"consumes": [
"application/json;charset=UTF-8",
"text/plain"
],
"produces": [
"application/json;charset=UTF-8",
"text/plain"
],
"paths": {
"/carts/{customerId}": {
"get": {
"description": "",
"operationId": "Get cart",
"produces": [
"application/json;charset=UTF-8"
],
"parameters": [
{
"name": "customerId",
"in": "path",
"required": true,
"type": "string",
"x-example": "1"
}
],
"responses": {
"200": {
"description": "Returns cart",
"schema": {
"$ref": "#/definitions/Getcartresponse"
}
}
}
},
"delete": {
"description": "",
"operationId": "Delete cart",
"produces": [
"application/json;charset=UTF-8"
],
"parameters": [
{
"name": "customerId",
"in": "path",
"required": true,
"type": "string",
"x-example": "1"
}
],
"responses": {
"202": {
"description": ""
}
}
}
},
"/carts/{customerId}/items": {
"post": {
"description": "",
"operationId": "Add an item to the cart",
"produces": [
"application/json;charset=UTF-8"
],
"parameters": [
{
"name": "customerId",
"in": "path",
"required": true,
"type": "string",
"x-example": "579f21ae98684924944651bf"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/CartItem",
"example": {
"itemId":"819e1fbf-8b7e-4f6d-811f-693534916a8b",
"quantity": 20,
"unitPrice" : 99.0
}
}
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/CartItem"
}
}
}
},
"patch": {
"description": "Update an item",
"operationId": "Update item",
"produces": [
"application/json;charset=UTF-8"
],
"parameters": [
{
"name": "customerId",
"in": "path",
"required": true,
"type": "string",
"x-example": "579f21ae98684924944651bf"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/carts/{customerId}/items/{itemId}": {
"delete": {
"description": "Delete cart item",
"operationId": "delete",
"parameters": [
{
"name": "itemId",
"in": "path",
"required": true,
"type": "string",
"x-example": "819e1fbf-8b7e-4f6d-811f-693534916a8b"
},
{
"name": "customerId",
"in": "path",
"required": true,
"type": "string",
"x-example": "579f21ae98684924944651bf"
}
],
"responses": {
"202": {
"description": "Delete response"
}
}
}
}
},
"definitions": {
"Getcartresponse": {
"title": "Get cart response",
"type": "object",
"properties": {
"customerId": {
"type": "string"
}
},
"required": [
"customerId"
]
},
"CartItem": {
"title": "Cart item",
"type": "object",
"properties": {
"itemId": {
"type": "string"
},
"quantity": {
"type": "integer"
},
"unitPrice": {
"type": "number"
}
},
"required": [
"itemId",
"quantity",
"unitPrice"
]
}
}
}
const hooks = require('hooks');
const {MongoClient} = require('mongodb');
const ObjectID = require('mongodb').ObjectID;
let db;
const address = [
{"_id":ObjectID("579f21ae98684924944651bd"),"_class":"works.weave.socks.accounts.entities.Address","number":"69","street":"Wilson Street","city":"Hartlepool","postcode":"TS26 8JU","country":"United Kingdom"},
{"_id":ObjectID("579f21ae98684924944651c0"),"_class":"works.weave.socks.accounts.entities.Address","number":"122","street":"Radstone WayNet","city":"Northampton","postcode":"NN2 8NT","country":"United Kingdom"},
{"_id":ObjectID("579f21ae98684924944651c3"),"_class":"works.weave.socks.accounts.entities.Address","number":"3","street":"Radstone Way","city":"Northampton","postcode":"NN2 8NT","country":"United Kingdom"}
];
const card = [
{"_id":ObjectID("579f21ae98684924944651be"),"_class":"works.weave.socks.accounts.entities.Card","longNum":"8575776807334952","expires":"08/19","ccv":"014"},
{"_id":ObjectID("579f21ae98684924944651c1"),"_class":"works.weave.socks.accounts.entities.Card","longNum":"8918468841895184","expires":"08/19","ccv":"597"},
{"_id":ObjectID("579f21ae98684924944651c4"),"_class":"works.weave.socks.accounts.entities.Card","longNum":"6426429851404909","expires":"08/19","ccv":"381"}
];
const cart = [
{"_id":ObjectID("579f21de98689ebf2bf1cd2f"),"_class":"works.weave.socks.cart.entities.Cart","customerId":"579f21ae98684924944651bf","items":[{"$ref":"item","$id":ObjectID("579f227698689ebf2bf1cd31")},{"$ref":"item","$id":ObjectID("579f22ac98689ebf2bf1cd32")}]},
{"_id":ObjectID("579f21e298689ebf2bf1cd30"),"_class":"works.weave.socks.cart.entities.Cart","customerId":"579f21ae98684924944651bfaa","items":[]}
];
const item = [
{"_id":ObjectID("579f227698689ebf2bf1cd31"),"_class":"works.weave.socks.cart.entities.Item","itemId":"819e1fbf-8b7e-4f6d-811f-693534916a8b","quantity":20,"unitPrice":99.0}
];
const customer = [
{"_id":"579f21ae98684924944651bf","_class":"works.weave.socks.accounts.entities.Customer","firstName":"Eve","lastName":"Berger","username":"Eve_Berger","addresses":[{"$ref":"address","$id":ObjectID("579f21ae98684924944651bd")}],"cards":[{"$ref":"card","$id":ObjectID("579f21ae98684924944651be")}]
},
{"_id":"579f21ae98684924944651c2","_class":"works.weave.socks.accounts.entities.Customer","firstName":"User","lastName":"Name","username":"user","addresses":[{"$ref":"address","$id":ObjectID("579f21ae98684924944651c0")}],"cards":[{"$ref":"card","$id":ObjectID("579f21ae98684924944651c1")}]},
{"_id":"579f21ae98684924944651c5","_class":"works.weave.socks.accounts.entities.Customer","firstName":"User1","lastName":"Name1","username":"user1","addresses":[{"$ref":"address","$id":ObjectID("579f21ae98684924944651c3")}],"cards":[{"$ref":"card","$id":ObjectID("579f21ae98684924944651c4")}]}
];
// Setup database connection before Dredd starts testing
hooks.beforeAll((transactions, done) => {
var MongoEndpoint = process.env.MONGO_ENDPOINT || 'mongodb://localhost:32769/data';
MongoClient.connect(MongoEndpoint, function(err, conn) {
if (err) {
console.error(err);
}
db = conn;
done(err);
});
});
hooks.beforeEach((transaction, done) => {
db.dropDatabase(function (err, res) {
var promisesToKeep = [
db.collection('customer').insertMany(customer),
db.collection('card').insertMany(card),
db.collection('cart').insertMany(cart),
db.collection('address').insertMany(address),
db.collection('item').insertMany(item)
];
Promise.all(promisesToKeep).then(function(vls) {
done();
}, function(vls) {
done();
});
})
});
hooks.before("/carts/{customerId}/items > POST", function(transaction, done) {
transaction.request.headers['Content-Type'] = 'application/json';
transaction.request.body = JSON.stringify(
{
"itemId":"819e1fbf-8b7e-4f6d-811f-693534916a8b",
"quantity": 20,
"unitPrice" : 99.0
}
);
done();
});
// TODO: Can't make POST and PUT work, skipping for now
// hooks.before("/carts/{customerId}/items > POST", function(transaction, done) {
// transaction.skip = true;
// done();
// });
hooks.before("/carts/{customerId}/items > PATCH", function(transaction, done) {
transaction.skip = true;
done();
});
......@@ -24,7 +24,7 @@ else
fi
CODE_DIR=$(cd $SCRIPT_DIR/..; pwd)
echo $CODE_DIR
$DOCKER_CMD run --rm -v $HOME/.m2:/root/.m2 -v $CODE_DIR:/usr/src/mymaven -w /usr/src/mymaven maven:3.2-jdk-8 mvn -DskipTests package
$DOCKER_CMD run --rm -v $HOME/.m2:/root/.m2 -v $CODE_DIR:/usr/src/mymaven -w /usr/src/mymaven maven:3.2-jdk-8 mvn -q -DskipTests package
cp $CODE_DIR/target/*.jar $CODE_DIR/docker/cart
......
import argparse
import sys
import unittest
import os
from util.Api import Api
from time import sleep
from util.Api import Api
from util.Docker import Docker
from util.Dredd import Dredd
class CartContainerTest(unittest.TestCase):
TAG = "latest"
COMMIT = ""
container_name = Docker().random_container_name('cart')
mongo_container_name = Docker().random_container_name('cart-db')
def __init__(self, methodName='runTest'):
super(CartContainerTest, self).__init__(methodName)
self.ip = ""
def setUp(self):
Docker().start_container(container_name=self.mongo_container_name, image="mongo", host="cart-db")
command = ['docker', 'run',
......@@ -25,7 +25,7 @@ class CartContainerTest(unittest.TestCase):
'-h', 'cart',
'--link',
CartContainerTest.mongo_container_name,
'weaveworksdemos/cart:' + self.TAG]
'weaveworksdemos/cart:' + self.COMMIT]
Docker().execute(command)
self.ip = Docker().get_container_ip(CartContainerTest.container_name)
......@@ -34,26 +34,34 @@ class CartContainerTest(unittest.TestCase):
Docker().kill_and_remove(CartContainerTest.mongo_container_name)
def test_api_validated(self):
limit = 60
while Api().noResponse('http://' + self.ip + ':80/carts/579f21ae98684924944651bf'):
limit = 30
while Api().noResponse('http://' + self.ip + ':80/carts/'):
if limit == 0:
self.fail("Couldn't get the API running")
limit = limit - 1
sleep(1)
out = Dredd().test_against_endpoint("carts/carts.json", CartContainerTest.container_name, "http://cart/",
"mongodb://cart-db:27017/data", self.mongo_container_name)
out = Dredd().test_against_endpoint(
"cart", "http://cart/",
links=[self.mongo_container_name, self.container_name],
env=[("MONGO_ENDPOINT", "mongodb://cart-db:27017/data")],
dump_streams=True)
self.assertGreater(out.find("0 failing"), -1)
self.assertGreater(out.find("0 errors"), -1)
print(out)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--tag', default="latest", help='The tag of the image to use. (default: latest)')
default_tag = "latest"
parser.add_argument('--tag', default=default_tag, help='The tag of the image to use. (default: latest)')
parser.add_argument('unittest_args', nargs='*')
args = parser.parse_args()
CartContainerTest.TAG = args.tag
if CartContainerTest.TAG == "":
CartContainerTest.TAG = default_tag
CartContainerTest.COMMIT = os.environ["COMMIT"]
# Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone)
sys.argv[1:] = args.unittest_args
unittest.main()
......@@ -21,14 +21,16 @@ echo "Testing $1"
CODE_DIR=$(cd $SCRIPT_DIR/..; pwd)
echo "$@"
$DOCKER_CMD run \
--rm \
--name test \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $CODE_DIR:$CODE_DIR -w $CODE_DIR \
-e COVERALLS_TOKEN=$COVERALLS_TOKEN \
-e TRAVIS_JOB_ID=$TRAVIS_JOB_ID \
-e TRAVIS_BRANCH=$TRAVIS_BRANCH \
-e TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST \
-e TRAVIS=$TRAVIS \
test-container \
sh -c export PYTHONPATH=\$PYTHONPATH:\$PWD/test ; python test/"$@"
--rm \
--name test \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $CODE_DIR:$CODE_DIR -w $CODE_DIR \
-e COVERALLS_TOKEN=$COVERALLS_TOKEN \
-e TRAVIS_JOB_ID=$TRAVIS_JOB_ID \
-e TRAVIS_BRANCH=$TRAVIS_BRANCH \
-e TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST \
-e TRAVIS=$TRAVIS \
-e TAG=$TAG \
-e COMMIT=$COMMIT \
test-container \
sh -c "export PYTHONPATH=\$PYTHONPATH:\$PWD/test ; python test/$@"
......@@ -11,7 +11,7 @@ class JavaServices(unittest.TestCase):
code_dir = script_dir + "/.."
home = expanduser("~")
command = ['docker', 'run', '--rm', '-v', home + '/.m2:/root/.m2', '-v', code_dir + ':/usr/src/mymaven', '-w',
'/usr/src/mymaven', 'maven:3.2-jdk-8', 'mvn', 'test']
'/usr/src/mymaven', 'maven:3.2-jdk-8', 'mvn', '-q', 'test']
print(Docker().execute(command))
......
import requests
class Api:
def noResponse(self, url):
try:
r = requests.get(url, timeout=5)
except requests.exceptions.ConnectionError:
return True
return r.status_code > 299
return False
import re
from random import random
from subprocess import Popen, PIPE
from random import random
# From http://blog.bordage.pro/avoid-docker-py/
class Docker:
def kill_and_remove(self, ctr_name):
command = ['docker', 'rm', '-f', ctr_name]
self.execute(command)
try:
self.execute(command)
return True
except RuntimeError as e:
print(e)
return False
def random_container_name(self, prefix):
retstr = prefix + '-'
for i in range(5):
retstr += chr(int(round(random() * (122 - 97) + 97)))
retstr += chr(int(round(random() * (122-97) + 97)))
return retstr
def get_container_ip(self, ctr_name):
......@@ -21,17 +25,13 @@ class Docker:
ctr_name]
return re.sub(r'[^0-9.]*', '', self.execute(command))
def execute(self, command):
def execute(self, command, dump_streams=False):
print("Running: " + ' '.join(command))
p = Popen(command, stdout=PIPE, stderr=PIPE)
out = p.stdout.read()
stderr = p.stderr.read()
if p.wait() != 0:
p.stdout.close()
p.stderr.close()
raise RuntimeError(str(stderr.decode('utf-8')))
p.stdout.close()
p.stderr.close()
out, err = p.communicate()
if dump_streams == True:
print(out.decode('utf-8'))
print(err.decode('utf-8'))
return str(out.decode('utf-8'))
def start_container(self, container_name="", image="", cmd="", host=""):
......
from util.Docker import Docker
from util.Api import Api
import os
import unittest
class Dredd:
image = 'weaveworksdemos/openapi'
image = 'weaveworksdemos/openapi:snapshot'
container_name = ''
def test_against_endpoint(self, json_spec, endpoint_container_name, api_endpoint, mongo_endpoint_url,
mongo_container_name):
def test_against_endpoint(self, service, api_endpoint, links=[], env=[], dump_streams=False):
self.container_name = Docker().random_container_name('openapi')
command = ['docker', 'run',
'-h', 'openapi',
'--name', self.container_name,
'--link', mongo_container_name,
'--link', endpoint_container_name,
'--env', "MONGO_ENDPOINT={0}".format(mongo_endpoint_url),
Dredd.image,
"/usr/src/app/{0}".format(json_spec),
api_endpoint,
"-f",
"/usr/src/app/hooks.js"
]
out = Docker().execute(command)
'-v', "{0}:{1}".format(os.getcwd() + "/api-spec/", "/tmp/specs/")]
if links != []:
[command.extend(["--link", x]) for x in links]
if env != []:
[command.extend(["--env", "{}={}".format(x[0], x[1])]) for x in env]
command.extend([Dredd.image,
"/tmp/specs/{0}.json".format(service),
api_endpoint,
"-f",
"/tmp/specs/hooks.js".format(service)])
out = Docker().execute(command, dump_streams=dump_streams)
Docker().kill_and_remove(self.container_name)
return out
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment