Fix functional tests & multiple bugfixes & use CES
This commit is contained in:
committed by
Brendan Le Glaunec
parent
5be5124e70
commit
58bcfb9ee5
+9
-7
@@ -2,14 +2,14 @@ FROM ubuntu:15.10
|
||||
|
||||
MAINTAINER brendan.leglaunec@etixgroup.com
|
||||
|
||||
ENV LD_LIBRARY_PATH="/cctv/libraries"
|
||||
ENV LD_LIBRARY_PATH="/cameradar/libraries"
|
||||
|
||||
# install go
|
||||
RUN apt-get update && apt-get install -y make git wget curl
|
||||
RUN wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz
|
||||
RUN tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz
|
||||
# set variable env
|
||||
ENV GOPATH=/go
|
||||
ENV GOPATH=/cameradartest/go
|
||||
ENV PATH=$PATH:/go/bin
|
||||
ENV PATH=$PATH:/usr/local/go/bin
|
||||
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
|
||||
@@ -27,17 +27,19 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
RUN apt-get install -y psmisc
|
||||
|
||||
ADD cctv_*_Debug_Linux.tar.gz /
|
||||
RUN mv cctv_*_Debug_Linux cctv
|
||||
ADD cameradar_*_Debug_Linux.tar.gz /
|
||||
RUN mv cameradar_*_Debug_Linux cameradar
|
||||
|
||||
# create cameradaratest folder in go src path
|
||||
RUN mkdir -p /go/src/cameradartest
|
||||
ADD ./conf /conf
|
||||
RUN mkdir -p /cameradartest/go/src/cameradartest
|
||||
COPY src/*.go /cameradartest/go/src/cameradartest/
|
||||
COPY ./conf /conf
|
||||
ADD ./docker/run_cameradartest.sh /run.sh
|
||||
|
||||
# get go deps
|
||||
RUN go get github.com/go-sql-driver/mysql
|
||||
|
||||
RUN mkdir /thumbnails
|
||||
WORKDIR /go/src/cameradartest
|
||||
WORKDIR /cameradartest/go/src/cameradartest
|
||||
RUN go build -o cameradartest *.go
|
||||
CMD ["/run.sh"]
|
||||
|
||||
+16
-7
@@ -1,14 +1,23 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER brendan.leglaunec@etixgroup.com
|
||||
|
||||
RUN useradd -m vlc; \
|
||||
apt-get update; \
|
||||
apt-get install -y vlc-nox
|
||||
|
||||
RUN sed -i s/geteuid/getppid/g /usr/bin/vlc
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libgstrtspserver-1.0-dev \
|
||||
libgstreamer1.0-dev \
|
||||
gstreamer1.0-plugins-base \
|
||||
gstreamer1.0-plugins-bad \
|
||||
gstreamer1.0-plugins-ugly \
|
||||
gstreamer1.0-libav \
|
||||
gstreamer1.0-tools \
|
||||
libssl-dev mysql-client \
|
||||
gstreamer1.0-plugins-good \
|
||||
libgstreamer-plugins-base1.0-dev \
|
||||
libgstreamer-plugins-bad1.0-dev
|
||||
|
||||
ADD ./docker/screen.png /vlc/screen.png
|
||||
COPY ./docker/run_vlc.sh /start.sh
|
||||
COPY ./etix_rtsp_server /etix_rtsp_server
|
||||
COPY ./docker/run_ces.sh /start.sh
|
||||
COPY ./camera_emulation_server /camera_emulation_server
|
||||
|
||||
EXPOSE 8554
|
||||
|
||||
RUN ./camera_emulation_server&
|
||||
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ESC_SEQ="\x1b["
|
||||
COL_RESET=$ESC_SEQ"39;49;00m"
|
||||
COL_RED=$ESC_SEQ"31;01m"
|
||||
COL_GREEN=$ESC_SEQ"32;01m"
|
||||
COL_YELLOW=$ESC_SEQ"33;01m"
|
||||
COL_BLUE=$ESC_SEQ"34;01m"
|
||||
COL_MAGENTA=$ESC_SEQ"35;01m"
|
||||
COL_CYAN=$ESC_SEQ"36;01m"
|
||||
|
||||
echo -e $COL_YELLOW"Deleting old package ... "$COL_RESET
|
||||
rm -f cameradar_*_Debug_Linux.tar.gz
|
||||
echo -e $COL_GREEN"OK!"$COL_RESET
|
||||
|
||||
echo -e $COL_YELLOW"Creating package ... "$COL_RESET
|
||||
{
|
||||
cd ..
|
||||
mkdir build
|
||||
cd build
|
||||
rm -f cameradar_*_Debug_Linux.tar.gz
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug
|
||||
make package
|
||||
cp cameradar_*_Debug_Linux.tar.gz ../test
|
||||
cd ../test
|
||||
} &> /dev/null
|
||||
echo -e $COL_GREEN"OK!"$COL_RESET
|
||||
Executable
BIN
Binary file not shown.
@@ -1,14 +1,16 @@
|
||||
{
|
||||
"mysql_db" : {
|
||||
"host" : "0.0.0.0",
|
||||
"host" : "cameradar-database",
|
||||
"port" : 3306,
|
||||
"user": "root",
|
||||
"password": "root",
|
||||
"db_name": "cctv"
|
||||
"db_name": "cmrdr"
|
||||
},
|
||||
"subnets" : "172.16.100.13 localhost",
|
||||
"ports" : "554,8554", // if not specified, default will be 1-65535
|
||||
"rtsp_url_file" : "conf/url.json",
|
||||
"rtsp_ids_file" : "conf/ids.json",
|
||||
"thumbnail_storage_path" : "/ce/que/tu/veux"
|
||||
}
|
||||
"subnets" : "localhost",
|
||||
"ports" : "554,8554",
|
||||
"rtsp_url_file" : "/conf/url.json",
|
||||
"rtsp_ids_file" : "/conf/ids.json",
|
||||
"thumbnail_storage_path" : "/tmp",
|
||||
"cache_manager_path" : "/cameradar/cache_managers",
|
||||
"cache_manager_name" : "dumb"
|
||||
}
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
"Output": "cameratest.log.xml",
|
||||
|
||||
"Cameradar" : {
|
||||
"Path": "/home/ullaakut/Work/cctv_server2/cameradar/test/cameradar",
|
||||
"Args": "-l 1 -c tmp_config",
|
||||
"Ports": "554,5554,8554",
|
||||
"IdsPath": "conf/ids.json",
|
||||
"RoutesPath": "conf/url.json",
|
||||
"ThumbPath": "/home/ullaakut/.cctv",
|
||||
"dbHost": "0.0.0.0",
|
||||
"dbPort": 3306,
|
||||
"dbUser": "root",
|
||||
"dbPassword": "root",
|
||||
"dbName": "cctv",
|
||||
"Console": false
|
||||
},
|
||||
"Path": "/cameradar/cameradar_standalone/cameradar",
|
||||
"Args": "-s 172.17.0.0/24 -c /conf/cameradar.conf.json --gst-rtsp-server",
|
||||
"Ports": "554,5554,8554",
|
||||
"IdsPath": "/conf/ids.json",
|
||||
"RoutesPath": "/conf/url.json",
|
||||
"ThumbPath": "/tmp",
|
||||
"dbHost": "cameradar-database",
|
||||
"dbPort": 3306,
|
||||
"dbUser": "root",
|
||||
"dbPassword": "root",
|
||||
"dbName": "cmrdr",
|
||||
"Console": false
|
||||
},
|
||||
"Tests" : [
|
||||
{
|
||||
"address" : "127.0.0.1",
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
{
|
||||
"Output": "cameratest.log.xml",
|
||||
"Cameradar" : {
|
||||
"Path": "/cctv/bin/cameradar",
|
||||
"Args": "-l 1 -c tmp_config",
|
||||
"Ports": "554,5554,8554,5548",
|
||||
"IdsPath": "/conf/ids.json",
|
||||
"RoutesPath": "/conf/url.json",
|
||||
"ThumbPath": "/thumbnails",
|
||||
"dbHost": "mysql_cameradar",
|
||||
"dbPort": 3306,
|
||||
"dbUser": "root",
|
||||
"dbPassword": "root",
|
||||
"dbName": "cctv",
|
||||
"Console": false
|
||||
"output": "test-results.xml",
|
||||
|
||||
"cameradar" : {
|
||||
"path": "/cameradar/bin/cameradar",
|
||||
"args": "-s 172.17.0.0/24 -c /conf/cameradar.conf.json --gst-rtsp-server",
|
||||
"ports": "554,5554,8554",
|
||||
"ids_path": "conf/ids.json",
|
||||
"routes_path": "conf/url.json",
|
||||
"thumb_path": "/tmp",
|
||||
"db_host": "cameradar-database",
|
||||
"db_port": 3306,
|
||||
"db_user": "root",
|
||||
"db_password": "root",
|
||||
"db_name": "cmrdr",
|
||||
"console": false
|
||||
},
|
||||
"Tests" : __CAMERAS__
|
||||
}
|
||||
"tests" : __CAMERAS__
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
ports=('8554' '8554' '8554' '8554' '8554' '8554')
|
||||
users=('admin' 'root' 'ubnt' 'Admin' 'supervisor' '')
|
||||
passwords=('admin' 'root' '12345' 'ubnt' 'password' '')
|
||||
routes=('live.sdp' 'live.sdp' 'ch001.sdp' '' 'invalid' 'live_mpeg4.sdp')
|
||||
routes=('cam0_0' 'live.sdp' 'ch001.sdp' 'cam' 'invalid' 'live_mpeg4.sdp')
|
||||
cams_name_pattern="fake_camera_"
|
||||
|
||||
# json generation variable only
|
||||
@@ -11,11 +11,16 @@ json="[\n"
|
||||
first=true
|
||||
# $1 = adress, $2 = port, $3 = path, $4 = usernam $5 = password, $6 = valid
|
||||
function make_json {
|
||||
# Get all data about the container, this will return three lines
|
||||
# One empty that we ignore
|
||||
# the two other ones with the IP of our container
|
||||
# We take the second one using sed and cut to get only the IPAddress
|
||||
address="$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CID)"
|
||||
if [ "$first" = true ] ; then first=false
|
||||
else json="$json,\n"; fi
|
||||
json="$json{"
|
||||
json="$json\"address\":\"$1\","
|
||||
json="$json\"port\":\"$2\","
|
||||
json="$json\"address\":\"$address\","
|
||||
json="$json\"port\":$2,"
|
||||
json="$json\"route\":\"$3\","
|
||||
json="$json\"username\":\"$4\","
|
||||
json="$json\"password\":\"$5\","
|
||||
@@ -50,13 +55,12 @@ function start {
|
||||
# if conf_idx = 4 -> invalid conf
|
||||
if [ "$conf_idx" == "4" ] ; then is_valid=false; fi
|
||||
|
||||
docker run -d --name "$name" fake-camera /start.sh "$port" "$user" "$passw" "$route"
|
||||
make_json "$name" "$port" "$route" "$user" "$passw" $is_valid
|
||||
CID=$(docker run -d --name "$name" fake-camera /start.sh "$port" "$user" "$passw" "$route");
|
||||
make_json "$name" "$port" "$route" "$user" "$passw" $is_valid $CID
|
||||
done
|
||||
|
||||
# finalize json
|
||||
json="$json]"
|
||||
echo "$json"
|
||||
}
|
||||
|
||||
function stop {
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
while ! mysqladmin ping -h"mysql_cameradar" -P3306 --silent; do
|
||||
while ! mysqladmin ping -h"cameradar-database" -P3306 --silent; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
ls -alhR /conf
|
||||
cat /etc/hosts
|
||||
cat /tmp/tests/cameradartest.conf.json
|
||||
|
||||
# build
|
||||
go build
|
||||
|
||||
cp /tmp/tests/*.xml ./
|
||||
|
||||
# run test
|
||||
./cameradartest /tmp/tests/cameradartest.conf.json
|
||||
|
||||
cp cameratest.log.xml /tmp/tests/
|
||||
cat *.xml
|
||||
|
||||
cp *.xml /tmp/tests/
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
port=$1
|
||||
user=$2
|
||||
passw=$3
|
||||
route=$4
|
||||
url=""
|
||||
|
||||
# need first argument at least
|
||||
if [ "$2" == "" ]; then
|
||||
url="rtsp://:$port/$route"
|
||||
else
|
||||
url="rtsp://$user:$passw@:$port/$route"
|
||||
fi
|
||||
|
||||
./camera_emulation_server -u $2 -p $3 -r $4
|
||||
echo "Stream started on ${url}"
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
port=$1
|
||||
user=$2
|
||||
passw=$3
|
||||
route=$4
|
||||
url=""
|
||||
|
||||
# need first argument at least
|
||||
if [ "$2" == "" ]; then
|
||||
url="rtsp://:$port/$route"
|
||||
else
|
||||
url="rtsp://$user:$passw@:$port/$route"
|
||||
fi
|
||||
./etix_rtsp_server -u $s -p $3 -r $4
|
||||
# cvlc /vlc/screen.png -I dummy --sout-keep --no-drop-late-frames --no-skip-frames --image-duration 9999 --sout="#transcode{vcodec=h264,fps=15,venc=x264{preset=ultrafast,tune=zerolatency,keyint=30,bframes=0,ref=1,level=30,profile=baseline,hrd=cbr,crf=20,ratetol=1.0,vbv-maxrate=1200,vbv-bufsize=1200,lookahead=0}}:rtp{sdp=$url}" --sout-all
|
||||
Binary file not shown.
+9
-9
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# check if a debug package exist in the current folder
|
||||
if ! ls ./cctv_*_Debug_Linux.tar.gz 1> /dev/null 2>&1; then
|
||||
if ! ls ./cameradar_*_Debug_Linux.tar.gz 1> /dev/null 2>&1; then
|
||||
(echo "no debug package in the current folder"; exit 137)
|
||||
exit 137
|
||||
fi
|
||||
@@ -19,40 +19,40 @@ function make_docker_command {
|
||||
done
|
||||
|
||||
# add mysql libk
|
||||
cmd="$cmd --link=\"mysql_cameradar\""
|
||||
cmd="$cmd --link=\"cameradar-database\""
|
||||
# add cameradar srcs
|
||||
cmd="$cmd -v \"`pwd`/src:/go/src/cameradartest\""
|
||||
# add cmaeradar conf
|
||||
cmd="$cmd -v \"`pwd`/:/tmp/tests\""
|
||||
# add container name
|
||||
cmd="$cmd -v \"`pwd`/:/tmp/shared\""
|
||||
# add container name
|
||||
cmd="$cmd cameradartest"
|
||||
}
|
||||
|
||||
function start_test {
|
||||
make_docker_command $1
|
||||
./docker/gen_cameras.sh start $1 ./docker/cameratest.conf.tmpl.json
|
||||
eval $cmd
|
||||
make_docker_command $1
|
||||
./docker/gen_cameras.sh stop
|
||||
}
|
||||
|
||||
# build images
|
||||
echo "building docker images"
|
||||
# building fake-camera container
|
||||
docker build -f Dockerfile-camera -t fake-camera .
|
||||
docker build --no-cache -f Dockerfile-camera -t fake-camera .
|
||||
|
||||
# building cameradartest image
|
||||
docker build -t cameradartest .
|
||||
docker build --no-cache -t cameradartest .
|
||||
|
||||
# getting mysql
|
||||
echo "starting mysql"
|
||||
docker pull mysql:5.7
|
||||
docker run --name mysql_cameradar -e MYSQL_DATABASE=cctv -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
|
||||
docker run --name cameradar-database -e MYSQL_DATABASE=cmrdr -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
|
||||
|
||||
start_test 1
|
||||
start_test 5
|
||||
# start_test 10
|
||||
# start_test 20
|
||||
|
||||
# stop mysql
|
||||
echo "stopping mysql"
|
||||
docker rm -f mysql_cameradar
|
||||
docker rm -f cameradar-database
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -6,27 +20,27 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func (m *manager) parseConfig() bool {
|
||||
func (t *Tester) parseConfig() bool {
|
||||
// Get config file path
|
||||
confPath := "conf/cameratest.conf.json"
|
||||
av := len(os.Args)
|
||||
if av == 2 {
|
||||
if av > 1 {
|
||||
confPath = os.Args[1]
|
||||
}
|
||||
|
||||
// Load config
|
||||
fmt.Printf("Loading config file: %s ... ", confPath)
|
||||
fmt.Printf("Loading Tester configuration file: %s ... ", confPath)
|
||||
configFile, err := os.Open(confPath)
|
||||
if err != nil {
|
||||
fmt.Printf("\nCan't open config file: %s\n", err)
|
||||
fmt.Printf("\nCan't open Tester configuration file: %s\n", err)
|
||||
return false
|
||||
}
|
||||
dec := json.NewDecoder(configFile)
|
||||
if err = dec.Decode(&m); err != nil {
|
||||
fmt.Printf("\nUnable to deserialize config file: %s\n", err)
|
||||
if err = dec.Decode(&t); err != nil {
|
||||
fmt.Printf("\nUnable to deserialize Tester configuration file: %s\n", err)
|
||||
return false
|
||||
}
|
||||
fmt.Println("Configuration file successfully loaded")
|
||||
fmt.Println("Tester configuration file successfully loaded")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
// MysqlDB contains the MySQL configuration
|
||||
type MysqlDB struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
DbName string `json:"db_name"`
|
||||
}
|
||||
|
||||
func (t *Tester) dropDB() bool {
|
||||
dsn := t.DB.User + ":" + t.DB.Password + "@" + "tcp(" + t.DB.Host + ":" + strconv.Itoa(t.DB.Port) + ")/" + t.DB.DbName + "?charset=utf8"
|
||||
db, err := sql.Open("mysql", dsn)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
defer db.Close()
|
||||
q := "DROP DATABASE " + t.DB.DbName + ";"
|
||||
_, err = db.Exec(q)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("------ Dropped CCTV Database -------")
|
||||
return true
|
||||
}
|
||||
|
||||
func (t *Tester) configureDatabase(DataBase *MysqlDB) bool {
|
||||
var db MysqlDB
|
||||
|
||||
db.Host = t.Cameradar.DbHost
|
||||
db.Port = t.Cameradar.DbPort
|
||||
db.User = t.Cameradar.DbUser
|
||||
db.Password = t.Cameradar.DbPassword
|
||||
db.DbName = t.Cameradar.DbName
|
||||
|
||||
*DataBase = db
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Launch it via goroutine
|
||||
// Start read log of service
|
||||
func readLog(service *Service, reader io.ReadCloser) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
str := scanner.Text()
|
||||
if service.Console {
|
||||
fmt.Printf("[%s] %s\n", service.Path, str)
|
||||
}
|
||||
fmt.Printf("%s\n", str)
|
||||
service.Mutex.Lock()
|
||||
service.Logs = append(service.Logs, str)
|
||||
service.Mutex.Unlock()
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
fmt.Printf("[%s] Service failed: %s\n", service.Path, err)
|
||||
}
|
||||
fmt.Printf("Logger of service: [%s] stopped\n", service.Path)
|
||||
service.Active = false
|
||||
}
|
||||
+19
-5
@@ -1,3 +1,17 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -5,24 +19,24 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
manager := new(manager)
|
||||
defer manager.Stop()
|
||||
Tester := new(Tester)
|
||||
defer Tester.Stop()
|
||||
|
||||
// Parse conf (streams should already be launched by Jenkins)
|
||||
fmt.Println("--- Initializing Cameradar Test Tool ... ---")
|
||||
if !manager.Init() {
|
||||
if !Tester.Init() {
|
||||
fmt.Println("-> Cameradar Test Tool initialization FAILED")
|
||||
return
|
||||
}
|
||||
|
||||
// Run tests
|
||||
if !manager.Run() {
|
||||
if !Tester.Run() {
|
||||
fmt.Println("-> Cameradar Test Tool FAILED")
|
||||
}
|
||||
|
||||
// Write results
|
||||
fmt.Println("--- Writing results... ---")
|
||||
if !manager.WriteResults(*(manager.Result), manager.Config.Output) {
|
||||
if !Tester.WriteResults(*(Tester.Result), Tester.Output) {
|
||||
fmt.Println("-> Write results FAILED")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Result contains the data of a Cameradar result, plus an error field in order to add error messages to the JUnit report
|
||||
type Result struct {
|
||||
Address string `json:"address"`
|
||||
IDsFound bool `json:"ids_found"`
|
||||
PathFound bool `json:"path_found"`
|
||||
Password string `json:"password"`
|
||||
Port int `json:"port"`
|
||||
Route string `json:"route"`
|
||||
ServiceName string `json:"service_name"`
|
||||
Protocol string `json:"protocol"`
|
||||
State string `json:"state"`
|
||||
Username string `json:"username"`
|
||||
Valid bool `json:"valid"`
|
||||
Thumb string `json:"thumbnail_path"`
|
||||
err error // in case of a fail, add a message
|
||||
}
|
||||
|
||||
// Launch it via goroutine
|
||||
// Start read log of service
|
||||
func getResult(test *[]Result, resultPath string) bool {
|
||||
// Load config
|
||||
resultFile, err := os.Open(resultPath)
|
||||
if err != nil {
|
||||
fmt.Printf("\nCan't open result file: %s\n", err)
|
||||
return false
|
||||
}
|
||||
dec := json.NewDecoder(resultFile)
|
||||
if err = dec.Decode(&test); err != nil {
|
||||
fmt.Printf("\nUnable to deserialize result file: %s\n", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isValid(e Result, r Result) bool {
|
||||
if e.Username != r.Username {
|
||||
e.err = errors.New(e.Address + " had a different username than " + r.Username)
|
||||
return false
|
||||
}
|
||||
if e.Password != r.Password {
|
||||
e.err = errors.New(e.Address + " had a different password than " + r.Password)
|
||||
return false
|
||||
}
|
||||
if e.Port != r.Port {
|
||||
e.err = errors.New(e.Address + " had a different port than expected")
|
||||
return false
|
||||
}
|
||||
if e.Valid != r.Valid {
|
||||
e.err = errors.New(e.Address + " had a different validity than expected")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Extend needs refacto
|
||||
func Extend(slice []Result, element Result) []Result {
|
||||
n := len(slice)
|
||||
if n == cap(slice) {
|
||||
// Slice is full; must grow.
|
||||
// We double its size and add 1, so if the size is zero we still grow.
|
||||
newSlice := make([]Result, len(slice), 2*len(slice)+1)
|
||||
copy(newSlice, slice)
|
||||
slice = newSlice
|
||||
}
|
||||
slice = slice[0 : n+1]
|
||||
slice[n] = element
|
||||
return slice
|
||||
}
|
||||
+28
-16
@@ -1,3 +1,17 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -9,24 +23,23 @@ import (
|
||||
|
||||
// Service needs refacto
|
||||
type Service struct {
|
||||
Path string `json:"Path"`
|
||||
Args string `json:"Args"`
|
||||
Ports string `json:"Ports"`
|
||||
IdsPath string `json:"IdsPath"`
|
||||
RoutesPath string `json:"RoutesPath"`
|
||||
DbHost string `json:"dbHost"`
|
||||
DbPort int `json:"dbPort"`
|
||||
DbUser string `json:"dbUser"`
|
||||
DbPassword string `json:"dbPassword"`
|
||||
DbName string `json:"dbName"`
|
||||
ThumbPath string `json:"ThumbPath"`
|
||||
Console bool `json:"Console"`
|
||||
Path string `json:"path"`
|
||||
Args string `json:"args"`
|
||||
Ports string `json:"ports"`
|
||||
IdsPath string `json:"ids_path"`
|
||||
RoutesPath string `json:"routes_path"`
|
||||
ThumbPath string `json:"thumb_path"`
|
||||
DbHost string `json:"db_host"`
|
||||
DbPort int `json:"db_port"`
|
||||
DbUser string `json:"db_user"`
|
||||
DbPassword string `json:"db_password"`
|
||||
DbName string `json:"db_name"`
|
||||
Console bool `json:"console"`
|
||||
|
||||
Logs []string
|
||||
Active bool // Based on io.ReadCloser status
|
||||
|
||||
Mutex sync.Mutex
|
||||
cmd *exec.Cmd // Go handler of the service
|
||||
Mutex sync.Mutex
|
||||
cmd *exec.Cmd // Go handler of the service
|
||||
}
|
||||
|
||||
func startService(service *Service) bool {
|
||||
@@ -77,7 +90,6 @@ func killService(service *Service) {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Sending SIGABORT, more reliable for VLC
|
||||
sigAbort := []string{service.Path, "-s", "SIGABRT"}
|
||||
fmt.Printf("Executing: killall %s -s SIGABRT\n", service.Path)
|
||||
cmd = exec.Command("killall", sigAbort...)
|
||||
|
||||
+52
-138
@@ -1,173 +1,87 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MysqlDB needs refacto
|
||||
type MysqlDB struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
DbName string `json:"db_name"`
|
||||
}
|
||||
|
||||
// CameradarConfig needs refacto
|
||||
type CameradarConfig struct {
|
||||
MysqlDB MysqlDB `json:"mysql_db"`
|
||||
Subnets string `json:"subnets"`
|
||||
Ports string `json:"ports"`
|
||||
RtspURLFile string `json:"rtsp_url_file"`
|
||||
RtspIdsFile string `json:"rtsp_ids_file"`
|
||||
ThumbnailStoragePath string `json:"thumbnail_storage_path"`
|
||||
}
|
||||
|
||||
// Result needs refacto
|
||||
type Result struct {
|
||||
Address string `json:"address"`
|
||||
Password string `json:"password"`
|
||||
Port string `json:"port"`
|
||||
Route string `json:"route"`
|
||||
Username string `json:"username"`
|
||||
Valid bool `json:"valid,omitempty"`
|
||||
Thumb string `json:"thumbnail_path,omitempty"`
|
||||
}
|
||||
|
||||
// TestCase needs refacto
|
||||
type TestCase struct {
|
||||
// Test represents a test launched with Cameradar
|
||||
type Test struct {
|
||||
expected []Result
|
||||
result []Result
|
||||
time time.Duration
|
||||
ok bool
|
||||
}
|
||||
|
||||
// Invoke the test
|
||||
// Wrap results in a TestResult object
|
||||
func (m *manager) invokeTestCase(testCase *TestCase, wg *sync.WaitGroup) {
|
||||
func (t *Tester) invokeTestCase(testCase *Test, wg *sync.WaitGroup) {
|
||||
startTime := time.Now()
|
||||
if m.runTestCase(testCase) {
|
||||
testCase.time = time.Since(startTime)
|
||||
testCase.ok = true
|
||||
fmt.Printf("Test OK in %.6fs\n", testCase.time.Seconds())
|
||||
} else {
|
||||
testCase.time = time.Since(startTime)
|
||||
testCase.ok = false
|
||||
fmt.Printf("Test failed in %.6fs\n", testCase.time.Seconds())
|
||||
}
|
||||
t.runTestCase(testCase)
|
||||
testCase.time = time.Since(startTime)
|
||||
fmt.Printf("Test OK in %.6fs\n", testCase.time.Seconds())
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
func (m *manager) runTestCase(test *TestCase) bool {
|
||||
fmt.Printf("Test triggered\n")
|
||||
|
||||
Cameradar := m.Config.Cameradar
|
||||
startService(&Cameradar)
|
||||
|
||||
for Cameradar.Active {
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
// Checks all valid results that are supposed to match
|
||||
// Adds them to the valid results and leave the failed
|
||||
// ones in the expected slice
|
||||
//
|
||||
// Then, if the result did not match the expected but it was supposed to fail
|
||||
// Add it to the valid results and remove it from the expected slice
|
||||
func (t *Tester) runTestCase(test *Test) {
|
||||
startService(&t.Cameradar)
|
||||
for t.Cameradar.Active {
|
||||
time.Sleep(25 * time.Millisecond)
|
||||
}
|
||||
found := 0
|
||||
toFind := len(test.expected)
|
||||
|
||||
var validResults []Result
|
||||
if getResult(&test.result, "result.json") {
|
||||
// Check all valid resutls that are supposed to match
|
||||
// Add them to the valid results and leave the failed
|
||||
// ones in the expected slice
|
||||
if getResult(&test.result, "/tmp/shared/result.json") {
|
||||
for _, r := range test.result {
|
||||
index := 0
|
||||
r.Valid = true
|
||||
for _, e := range test.expected {
|
||||
e.Thumb = r.Thumb
|
||||
var err error
|
||||
var addr []string
|
||||
addr, err = net.LookupHost(e.Address)
|
||||
e.Address = addr[0]
|
||||
if e == r {
|
||||
_, err = os.Stat(r.Thumb)
|
||||
if err == nil {
|
||||
fmt.Println("The result of ", r.Address, " is valid and the thumbnails were generated by Cameradar.")
|
||||
found++
|
||||
validResults = Extend(validResults, r)
|
||||
for index, e := range test.expected {
|
||||
if e.Address == r.Address && isValid(e, r) {
|
||||
// _, err := os.Stat(r.Thumb)
|
||||
// if err == nil) {
|
||||
fmt.Println("The result of ", r.Address, " is valid and the thumbnails were generated by Cameradar.")
|
||||
validResults = Extend(validResults, r)
|
||||
if len(test.expected) > 1 {
|
||||
test.expected = append(test.expected[:index], test.expected[index+1:]...)
|
||||
break
|
||||
} else {
|
||||
fmt.Println("The result of ", r.Address, " seemed valid, but the thumbnails could not be generated by Cameradar.")
|
||||
}
|
||||
break
|
||||
// } else {
|
||||
// e.err = error{"The result of " + e.Address + " seemed valid, but the thumbnails could not be generated by Cameradar : " + err.Error()}
|
||||
// }
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
index := 0
|
||||
// If the result did not match the expected but it was supposed to fail
|
||||
// Add it to the valid results and remove it from the expected slice
|
||||
for _, e := range test.expected {
|
||||
for index, e := range test.expected {
|
||||
if !e.Valid {
|
||||
found++
|
||||
fmt.Println("The result of", e.Address, "successfully failed.")
|
||||
validResults = Extend(validResults, e)
|
||||
test.expected = append(test.expected[:index], test.expected[index+1:]...)
|
||||
break
|
||||
if len(test.expected) > 1 {
|
||||
test.expected = append(test.expected[:index], test.expected[index+1:]...)
|
||||
}
|
||||
} else {
|
||||
e.err = errors.New("The camera with the address " + e.Address + " was not found by cameradar")
|
||||
fmt.Println("Should have been valid but was not found : ", e.Address)
|
||||
}
|
||||
index++
|
||||
}
|
||||
// If we found all the expected results, return true
|
||||
if found == toFind {
|
||||
return true
|
||||
}
|
||||
test.result = validResults
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *manager) generateConfig(test []Result, DataBase *mysql_db) bool {
|
||||
var config CameradarConfig
|
||||
var db mysql_db
|
||||
|
||||
db.Host = m.Config.Cameradar.DbHost
|
||||
db.Port = m.Config.Cameradar.DbPort
|
||||
db.User = m.Config.Cameradar.DbUser
|
||||
db.Password = m.Config.Cameradar.DbPassword
|
||||
db.Db_name = m.Config.Cameradar.DbName
|
||||
|
||||
for _, t := range test {
|
||||
if len(config.Subnets) > 0 {
|
||||
config.Subnets += ","
|
||||
}
|
||||
config.Subnets += t.Address
|
||||
}
|
||||
config.Mysql_db = db
|
||||
config.Ports = m.Config.Cameradar.Ports
|
||||
config.Rtsp_url_file = m.Config.Cameradar.RoutesPath
|
||||
config.Rtsp_ids_file = m.Config.Cameradar.IdsPath
|
||||
config.Thumbnail_storage_path = m.Config.Cameradar.ThumbPath
|
||||
b, _ := json.Marshal(config)
|
||||
fmt.Println(string(b))
|
||||
err := ioutil.WriteFile("tmp_config", b, 0644)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return false
|
||||
}
|
||||
*DataBase = db
|
||||
return true
|
||||
}
|
||||
|
||||
// Extend needs refacto
|
||||
func Extend(slice []Result, element Result) []Result {
|
||||
n := len(slice)
|
||||
if n == cap(slice) {
|
||||
// Slice is full; must grow.
|
||||
// We double its size and add 1, so if the size is zero we still grow.
|
||||
newSlice := make([]Result, len(slice), 2*len(slice)+1)
|
||||
copy(newSlice, slice)
|
||||
slice = newSlice
|
||||
}
|
||||
slice = slice[0 : n+1]
|
||||
slice[n] = element
|
||||
return slice
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Tester is the structure that will manage the whole testing
|
||||
type Tester struct {
|
||||
Cameradar Service `json:"cameradar"`
|
||||
Output string
|
||||
|
||||
Tests []Result
|
||||
Result *Test
|
||||
DB MysqlDB
|
||||
}
|
||||
|
||||
// Init gets the testing configuration and makes sure that no other Cameradar service is running at the moment
|
||||
func (t *Tester) Init() bool {
|
||||
fmt.Println("- Parsing")
|
||||
if !t.parseConfig() {
|
||||
return false
|
||||
}
|
||||
|
||||
fmt.Println("- Cleaning content")
|
||||
killService(&t.Cameradar)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Run launches the tests that have been set up by the init method
|
||||
func (t *Tester) Run() bool {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
fmt.Println("\n- Launching all tests")
|
||||
var newTest = new(Test)
|
||||
newTest.expected = t.Tests
|
||||
if t.configureDatabase(&t.DB) {
|
||||
t.dropDB()
|
||||
wg.Add(1)
|
||||
go t.invokeTestCase(newTest, &wg)
|
||||
t.Result = newTest
|
||||
}
|
||||
wg.Wait()
|
||||
fmt.Println("All tests completed")
|
||||
return true
|
||||
}
|
||||
|
||||
// Stop kills the service launched by the tester
|
||||
func (t *Tester) Stop() bool {
|
||||
killService(&t.Cameradar)
|
||||
return true
|
||||
}
|
||||
+66
-63
@@ -1,11 +1,26 @@
|
||||
// Copyright 2016 Etix Labs
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////
|
||||
@@ -13,21 +28,23 @@ import (
|
||||
|
||||
// JUnitTestSuites is a collection of JUnit test suites.
|
||||
type JUnitTestSuites struct {
|
||||
XMLName xml.Name `xml:"testsuites"`
|
||||
Suites []JUnitTestSuite
|
||||
XMLName xml.Name `xml:"testsuites"`
|
||||
TestSuites []JUnitTestSuite `xml:"testsuite"`
|
||||
}
|
||||
|
||||
// JUnitTestSuite is a single JUnit test suite which may contain many
|
||||
// testcases.
|
||||
type JUnitTestSuite struct {
|
||||
Tests int `xml:"tests,attr"`
|
||||
Failures int `xml:"failures,attr"`
|
||||
Time string `xml:"time,attr"`
|
||||
TestCases []JUnitTestCase
|
||||
XMLName xml.Name `xml:"testsuite"`
|
||||
Tests int `xml:"tests,attr"`
|
||||
Failures int `xml:"failures,attr"`
|
||||
Time string `xml:"time,attr"`
|
||||
TestCases []JUnitTestCase `xml:"testcase"`
|
||||
}
|
||||
|
||||
// JUnitTestCase is a single test case with its result.
|
||||
type JUnitTestCase struct {
|
||||
XMLName xml.Name `xml:"testcase"`
|
||||
Message string `xml:"message,attr"`
|
||||
Time string `xml:"time,attr"`
|
||||
Failure *JUnitFailure `xml:"failure,omitempty"`
|
||||
@@ -35,25 +52,25 @@ type JUnitTestCase struct {
|
||||
|
||||
// JUnitFailure contains data related to a failed test.
|
||||
type JUnitFailure struct {
|
||||
Message string `xml:"message,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
Contents string `xml:",chardata"`
|
||||
XMLName xml.Name `xml:"failure"`
|
||||
Message string `xml:"message,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
Contents string `xml:",chardata"`
|
||||
}
|
||||
|
||||
func (m *manager) WriteResults(result TestCase, output string) bool {
|
||||
// WriteResults will output the results in the standard output as well as concatenate them in an XML JUnit report
|
||||
func (t *Tester) WriteResults(result Test, output string) bool {
|
||||
fmt.Printf("Displaying results...\n")
|
||||
// Write Console report
|
||||
m.writeConsoleReport(result)
|
||||
t.writeConsoleReport(result)
|
||||
|
||||
// Write XML report
|
||||
// Open xml
|
||||
file, err := os.OpenFile(output, os.O_RDONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Error opening XML: %s\n", err)
|
||||
return false
|
||||
}
|
||||
defer file.Close()
|
||||
err = m.writeJUnitReportXML(result, file, output)
|
||||
|
||||
err = t.writeJUnitReportXML(result, file, output)
|
||||
if err != nil {
|
||||
fmt.Printf("Error writing XML: %s\n", err)
|
||||
return false
|
||||
@@ -63,42 +80,47 @@ func (m *manager) WriteResults(result TestCase, output string) bool {
|
||||
}
|
||||
|
||||
// Write tests results under JUnit format on w
|
||||
func (m *manager) writeJUnitReportXML(result TestCase, r io.ReadWriter, output string) error {
|
||||
func (t *Tester) writeJUnitReportXML(result Test, rw io.ReadWriter, output string) error {
|
||||
suites := JUnitTestSuites{}
|
||||
dec := xml.NewDecoder(r)
|
||||
if err := dec.Decode(&suites); err != nil {
|
||||
fmt.Printf("\nUnable to deserialize XML log file: %s\n", err)
|
||||
|
||||
buf, err := ioutil.ReadFile(output)
|
||||
|
||||
dec := xml.NewDecoder(bytes.NewBufferString(string(buf)))
|
||||
err = dec.Decode(&suites)
|
||||
if err != nil {
|
||||
fmt.Printf("\nUnable to deserialize %s file: %s\n", output, err)
|
||||
}
|
||||
|
||||
ts := JUnitTestSuite{
|
||||
Tests: len(result.result) + len(result.expected),
|
||||
Failures: 0,
|
||||
Time: fmt.Sprintf("%.6f", result.time.Seconds()),
|
||||
TestCases: []JUnitTestCase{},
|
||||
}
|
||||
// Run throught all iterations
|
||||
testCase := JUnitTestCase{
|
||||
Time: fmt.Sprintf("%.6f", result.time.Seconds()),
|
||||
Failure: nil,
|
||||
|
||||
for _, r := range result.result {
|
||||
testCase := JUnitTestCase{
|
||||
Time: fmt.Sprintf("%.6f", result.time.Seconds()),
|
||||
Failure: nil,
|
||||
}
|
||||
testCase.Message = "The stream " + r.Address + " could be accessed and its thumbnail was properly generated"
|
||||
ts.TestCases = append(ts.TestCases, testCase)
|
||||
}
|
||||
if len(result.result) > 0 {
|
||||
testCase.Message = "These streams matched what we expected:"
|
||||
}
|
||||
for _, success := range result.result {
|
||||
testCase.Message += " " + success.Address
|
||||
}
|
||||
if !result.ok {
|
||||
testCase.Failure = &JUnitFailure{
|
||||
Message: "These streams did not match what we expected:",
|
||||
Type: "",
|
||||
|
||||
for _, e := range result.expected {
|
||||
testCase := JUnitTestCase{
|
||||
Time: fmt.Sprintf("%.6f", result.time.Seconds()),
|
||||
Failure: nil,
|
||||
}
|
||||
if e.err != nil {
|
||||
testCase.Failure = &JUnitFailure{
|
||||
Message: e.err.Error(),
|
||||
Type: "",
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, fail := range result.expected {
|
||||
ts.Failures++
|
||||
testCase.Failure.Message += " " + fail.Address
|
||||
}
|
||||
ts.TestCases = append(ts.TestCases, testCase)
|
||||
|
||||
suites.Suites = append(suites.Suites, ts)
|
||||
suites.TestSuites = append(suites.TestSuites, ts)
|
||||
// Fix indent
|
||||
bytes, err := xml.MarshalIndent(suites, "", "\t")
|
||||
if err != nil {
|
||||
@@ -112,35 +134,16 @@ func (m *manager) writeJUnitReportXML(result TestCase, r io.ReadWriter, output s
|
||||
}
|
||||
writer := io.Writer(w)
|
||||
writer.Write(bytes)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) writeConsoleReport(result TestCase) bool {
|
||||
min := 50 * time.Hour
|
||||
max := 0 * time.Second
|
||||
total := 0 * time.Second
|
||||
successCount := 0
|
||||
failureCount := 0
|
||||
if result.ok {
|
||||
successCount++
|
||||
total += result.time
|
||||
if result.time < min {
|
||||
min = result.time
|
||||
}
|
||||
if result.time > max {
|
||||
max = result.time
|
||||
}
|
||||
} else {
|
||||
failureCount++
|
||||
}
|
||||
func (t *Tester) writeConsoleReport(result Test) bool {
|
||||
successCount := len(result.result)
|
||||
failureCount := len(result.expected)
|
||||
fmt.Println("--- Test summary ---")
|
||||
if successCount > 0 {
|
||||
fmt.Printf("Results: %d/%d (%d%%)\n", successCount, successCount+failureCount, successCount*100/(successCount+failureCount))
|
||||
fmt.Printf("Total time: %.6fs\n", total.Seconds())
|
||||
fmt.Printf("Average time: %.6fs\n", total.Seconds()/float64(successCount))
|
||||
fmt.Printf("Min time: %.6fs\n", min.Seconds())
|
||||
fmt.Printf("Max time: %.6fs\n", max.Seconds())
|
||||
fmt.Printf("Time: %.6fs\n", result.time.Seconds())
|
||||
} else {
|
||||
fmt.Printf("No test in success\n")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user