Skip to content

Commit 5b68098

Browse files
committed
Merge pull request #2868 from mboersma/store-mock-functional
Use store-mock container in functional tests
2 parents 809725f + b4564fe commit 5b68098

8 files changed

Lines changed: 173 additions & 100 deletions

File tree

database/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ test-unit:
4949
@echo no unit tests
5050

5151
test-functional:
52+
@docker history deis/mock-store >/dev/null 2>&1 || $(MAKE) -C ../tests/ mock-store
5253
@docker history deis/test-etcd >/dev/null 2>&1 || docker pull deis/test-etcd:latest
5354
GOPATH=`cd ../tests/ && godep path`:$(GOPATH) go test -v ./tests/...

registry/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ test-unit:
4949
@echo no unit tests
5050

5151
test-functional:
52+
@docker history deis/mock-store >/dev/null 2>&1 || $(MAKE) -C ../tests/ mock-store
5253
@docker history deis/test-etcd >/dev/null 2>&1 || docker pull deis/test-etcd:latest
5354
GOPATH=`cd ../tests/ && godep path`:$(GOPATH) go test -v ./tests/...

tests/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
include ../includes.mk
2+
3+
MOCK_STORE_IMAGE = $(IMAGE_PREFIX)mock-store:latest
4+
15
test: test-smoke
26

37
test-smoke: test-style
@@ -22,6 +26,9 @@ setup-root-gotools:
2226
setup-gotools:
2327
go get -v github.com/golang/lint/golint
2428

29+
mock-store:
30+
docker build -t $(MOCK_STORE_IMAGE) fixtures/mock-store/
31+
2532
test-style:
2633
go vet -x ./...
2734
-golint ./...
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM ubuntu-debootstrap:14.04
2+
3+
ENV DEBIAN_FRONTEND noninteractive
4+
5+
WORKDIR /app
6+
EXPOSE 8888
7+
CMD ["/app/bin/boot"]
8+
ADD bin/boot /app/bin/boot
9+
10+
ADD build.sh /tmp/build.sh
11+
RUN DOCKER_BUILD=true /tmp/build.sh
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Mock S3 storage
2+
3+
The objective is to provide an S3-compatible service for tests, so a Ceph cluster
4+
is not required. This component uses [mock-s3](https://github.com/jserver/mock-s3).
5+
6+
## Usage:
7+
8+
```
9+
docker run -p 8888:8888 -e HOST=$COREOS_PRIVATE_IPV4 -v <local directory>:/app/storage deis/mock-store
10+
```
11+
12+
*The use of a local directory `(-v <local directory>)` is optional*
13+
14+
15+
`mock-s3` does not requires an `ACCESS_KEY` and `SECRET_KEY` (there is no concept of permissions), but this
16+
component will generate both to keep compatibility with `deis-store-gateway`.
17+
18+
## Containers
19+
20+
The mock store component is composed of one container:
21+
22+
* [mock-store](https://index.docker.io/u/deis/mock-store/) - the blob store gateway,
23+
offering a S3-compatible bucket APIs using the local filesystem as storage.
24+
25+
## Usage
26+
27+
Please consult the [Makefile](Makefile) for current instructions on how to build, test, push,
28+
install, and start **deis/mock-store**.
29+
30+
## License
31+
32+
© 2015 OpDemand LLC
33+
34+
Licensed under the Apache License, Version 2.0 (the "License"); you may
35+
not use this file except in compliance with the License. You may obtain
36+
a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
37+
38+
Unless required by applicable law or agreed to in writing, software
39+
distributed under the License is distributed on an "AS IS" BASIS,
40+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41+
See the License for the specific language governing permissions and
42+
limitations under the License.

tests/fixtures/mock-store/bin/boot

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
#
3+
# This script is designed to be run inside the container
4+
#
5+
6+
# fail hard and fast even on pipelines
7+
set -eo pipefail
8+
9+
# set debug based on envvar
10+
[[ $DEBUG ]] && set -x
11+
12+
# configure etcd
13+
export ETCD_PORT=${ETCD_PORT:-4001}
14+
export ETCD="$HOST:$ETCD_PORT"
15+
export ETCD_PATH=${ETCD_PATH:-/deis/store/gateway}
16+
export ETCD_TTL=${ETCD_TTL:-10}
17+
18+
export EXTERNAL_PORT=${EXTERNAL_PORT:-8888}
19+
export STORAGE_DIRECTORY=${STORAGE_DIRECTORY:-/app/storage}
20+
21+
# wait for etcd to be available
22+
until etcdctl --no-sync -C $ETCD ls >/dev/null 2>&1; do
23+
echo "waiting for etcd at $ETCD..."
24+
sleep $(($ETCD_TTL/2)) # sleep for half the TTL
25+
done
26+
27+
# wait until etcd has discarded potentially stale values
28+
sleep $(($ETCD_TTL+1))
29+
30+
function etcd_safe_mkdir {
31+
set +e
32+
etcdctl --no-sync -C $ETCD mkdir $1 >/dev/null 2>&1
33+
if [[ $? -ne 0 && $? -ne 4 ]]; then
34+
echo "etcd_safe_mkdir: an etcd error occurred. aborting..."
35+
exit 1
36+
fi
37+
set -e
38+
}
39+
40+
etcd_safe_mkdir $ETCD_PATH
41+
42+
# store the access key and secret key for consumption by other services
43+
ACCESS_KEY=`etcdctl --no-sync -C $ETCD get $ETCD_PATH/accessKey 2>/dev/null || openssl rand -base64 21 | tr -d '\n'`
44+
SECRET_KEY=`etcdctl --no-sync -C $ETCD get $ETCD_PATH/secretKey 2>/dev/null || openssl rand -base64 64 | tr -d '\n'`
45+
etcdctl --no-sync -C $ETCD set $ETCD_PATH/accessKey ${ACCESS_KEY} >/dev/null
46+
etcdctl --no-sync -C $ETCD set $ETCD_PATH/secretKey ${SECRET_KEY} >/dev/null
47+
48+
mkdir -p /app/storage
49+
50+
mock_s3 --hostname 0.0.0.0 --port $EXTERNAL_PORT --root $STORAGE_DIRECTORY &
51+
52+
echo deis-store-gateway running...
53+
54+
# configure service discovery
55+
PROTO=${PROTO:-tcp}
56+
57+
set +e
58+
59+
# wait for the service to become available on PUBLISH port
60+
sleep 1 && while [[ -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PUBLISH\" && \$1 ~ \"$PROTO.?\"") ]] ; do sleep 1; done
61+
62+
# while the port is listening, publish to etcd
63+
while [[ ! -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PUBLISH\" && \$1 ~ \"$PROTO.?\"") ]] ; do
64+
etcdctl --no-sync -C $ETCD set $ETCD_PATH/host $HOST --ttl $ETCD_TTL >/dev/null
65+
etcdctl --no-sync -C $ETCD set $ETCD_PATH/port $EXTERNAL_PORT --ttl $ETCD_TTL >/dev/null
66+
sleep $(($ETCD_TTL/2)) # sleep for half the TTL
67+
done
68+
69+
# if the loop quits, something went wrong
70+
exit 1

tests/fixtures/mock-store/build.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
3+
# fail on any command exiting non-zero
4+
set -eo pipefail
5+
6+
if [[ -z $DOCKER_BUILD ]]; then
7+
echo
8+
echo "Note: this script is intended for use by the Dockerfile and not as a way to build the store mock component locally"
9+
echo
10+
exit 1
11+
fi
12+
13+
# install required packages to build
14+
apt-get update \
15+
&& apt-get install -y build-essential git python-dev curl net-tools
16+
17+
# install etcdctl
18+
curl -sSL -o /usr/local/bin/etcdctl https://s3-us-west-2.amazonaws.com/opdemand/etcdctl-v0.4.6 \
19+
&& chmod +x /usr/local/bin/etcdctl
20+
21+
22+
git clone https://github.com/jserver/mock-s3 /app/mock-s3
23+
24+
cd /app/mock-s3
25+
26+
# install pip
27+
curl -sSL https://raw.githubusercontent.com/pypa/pip/1.5.6/contrib/get-pip.py | python -
28+
29+
python setup.py install
30+
31+
# cleanup. indicate that python, libpq and libyanl are required packages.
32+
apt-mark unmarkauto python && \
33+
apt-get remove -y --purge build-essential python-dev gcc cpp git && \
34+
apt-get autoremove -y --purge && \
35+
apt-get clean -y && \
36+
rm -Rf /usr/share/man /usr/share/doc && \
37+
rm -rf /tmp/* /var/tmp/* && \
38+
rm -rf /var/lib/apt/lists/*
39+

tests/mock/mock.go

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -57,30 +57,11 @@ func RunMockDatabase(t *testing.T, tag string, etcdPort string, dbPort string) {
5757
func RunMockCeph(t *testing.T, name string, cli *client.DockerCli, etcdPort string) {
5858

5959
etcdutils.SetSingle(t, "/deis/store/hosts/"+utils.HostAddress(), utils.HostAddress(), etcdPort)
60-
61-
// since we're only running one OSD, our default of 128 placement groups is too large
62-
etcdutils.SetSingle(t, "/deis/store/pgNum", "64", etcdPort)
63-
64-
monitorName := name + "-monitor"
65-
RunMockCephMonitor(t, monitorName, etcdPort)
66-
67-
daemonName := name + "-daemon"
68-
RunMockCephDaemon(t, daemonName, etcdPort)
69-
70-
metadataName := name + "-metadata"
71-
RunMockCephMetadata(t, metadataName, etcdPort)
72-
73-
gatewayName := name + "-gateway"
74-
RunMockCephGateway(t, gatewayName, utils.RandomPort(), etcdPort)
75-
}
76-
77-
// RunMockCephMonitor runs a Ceph Monitor agent
78-
func RunMockCephMonitor(t *testing.T, name string, etcdPort string) {
7960
var err error
8061
cli, stdout, stdoutPipe := dockercli.NewClient()
81-
cephImage := "deis/store-monitor:" + utils.BuildTag()
62+
cephImage := "deis/mock-store:latest"
8263
ipaddr := utils.HostAddress()
83-
fmt.Printf("--- Running deis/mock-ceph-monitor at %s\n", ipaddr)
64+
fmt.Printf("--- Running deis/mock-store at %s\n", ipaddr)
8465
done2 := make(chan bool, 1)
8566
go func() {
8667
done2 <- true
@@ -90,88 +71,9 @@ func RunMockCephMonitor(t *testing.T, name string, etcdPort string) {
9071
"--rm",
9172
"-e", "HOST="+ipaddr,
9273
"-e", "ETCD_PORT="+etcdPort,
93-
"-e", "NUM_STORES=1",
9474
"--net=host",
9575
cephImage)
9676
}()
97-
dockercli.PrintToStdout(t, stdout, stdoutPipe, "monmap e1: 1 mons at")
98-
if err != nil {
99-
t.Fatal(err)
100-
}
101-
}
102-
103-
// RunMockCephDaemon sets up a single Ceph OSD
104-
func RunMockCephDaemon(t *testing.T, name string, etcdPort string) {
105-
var err error
106-
cli, stdout, stdoutPipe := dockercli.NewClient()
107-
cephImage := "deis/store-daemon:" + utils.BuildTag()
108-
ipaddr := utils.HostAddress()
109-
fmt.Printf("--- Running deis/mock-ceph-daemon at %s\n", ipaddr)
110-
done := make(chan bool, 1)
111-
go func() {
112-
done <- true
113-
_ = cli.CmdRm("-f", name)
114-
err = dockercli.RunContainer(cli,
115-
"--name", name,
116-
"--rm",
117-
"-e", "HOST="+ipaddr,
118-
"-e", "ETCD_PORT="+etcdPort,
119-
"--net=host",
120-
cephImage)
121-
}()
122-
dockercli.PrintToStdout(t, stdout, stdoutPipe, "journal close /var/lib/ceph/osd/ceph-0/journal")
123-
if err != nil {
124-
t.Fatal(err)
125-
}
126-
}
127-
128-
// RunMockCephMetadata starts a mock Ceph MDS
129-
func RunMockCephMetadata(t *testing.T, name string, etcdPort string) {
130-
var err error
131-
cli, stdout, stdoutPipe := dockercli.NewClient()
132-
cephImage := "deis/store-metadata:" + utils.BuildTag()
133-
ipaddr := utils.HostAddress()
134-
fmt.Printf("--- Running deis/mock-ceph-metadata at %s\n", ipaddr)
135-
done2 := make(chan bool, 1)
136-
go func() {
137-
done2 <- true
138-
_ = cli.CmdRm("-f", name)
139-
err = dockercli.RunContainer(cli,
140-
"--name", name,
141-
"--rm",
142-
"-e", "ETCD_PORT="+etcdPort,
143-
"-e", "HOST="+ipaddr,
144-
"--net=host",
145-
cephImage)
146-
}()
147-
dockercli.PrintToStdout(t, stdout, stdoutPipe, "mds.0.1 active_start")
148-
if err != nil {
149-
t.Fatal(err)
150-
}
151-
}
152-
153-
// RunMockCephGateway starts a mock S3 endpoint used for component testing
154-
func RunMockCephGateway(t *testing.T, name string, port string, etcdPort string) {
155-
var err error
156-
cli, stdout, stdoutPipe := dockercli.NewClient()
157-
cephImage := "deis/store-gateway:" + utils.BuildTag()
158-
ipaddr := utils.HostAddress()
159-
cephAddr := ipaddr + ":" + port
160-
fmt.Printf("--- Running deis/mock-ceph-gateway at %s\n", cephAddr)
161-
done2 := make(chan bool, 1)
162-
go func() {
163-
done2 <- true
164-
_ = cli.CmdRm("-f", name)
165-
err = dockercli.RunContainer(cli,
166-
"--name", name,
167-
"-h", "deis-store-gateway",
168-
"--rm",
169-
"-p", port+":"+"8888",
170-
"-e", "ETCD_PORT="+etcdPort,
171-
"-e", "HOST="+ipaddr,
172-
"-e", "EXTERNAL_PORT="+port,
173-
cephImage)
174-
}()
17577
dockercli.PrintToStdout(t, stdout, stdoutPipe, "deis-store-gateway running...")
17678
if err != nil {
17779
t.Fatal(err)

0 commit comments

Comments
 (0)