HW15 WIP
This commit is contained in:
parent
8680c3a85c
commit
a0b572be3a
@ -1,14 +1,5 @@
|
|||||||
cdir = $(shell pwd)
|
cdir = $(shell pwd)
|
||||||
|
|
||||||
build-all:
|
|
||||||
go build -o ./bin/calendar ./cmd/calendar/main.go
|
|
||||||
go build -o ./bin/scheduler ./cmd/scheduler/main.go
|
|
||||||
go build -o ./bin/sender ./cmd/sender/main.go
|
|
||||||
|
|
||||||
start: build-all rabbit-start calendar-start scheduler-start sender-start
|
|
||||||
|
|
||||||
stop: scheduler-stop sender-stop calendar-stop rabbit-stop
|
|
||||||
|
|
||||||
integration-test:
|
integration-test:
|
||||||
go test -count 10 -race ./cmd/calendar/... --config ./../../configs/calendar.conf
|
go test -count 10 -race ./cmd/calendar/... --config ./../../configs/calendar.conf
|
||||||
|
|
||||||
@ -25,35 +16,31 @@ generate:
|
|||||||
protoc -I ./api/public --go_out=plugins=grpc:./pkg/api/public --grpc-gateway_out=logtostderr=true:./pkg/api/public ./api/public/public.proto
|
protoc -I ./api/public --go_out=plugins=grpc:./pkg/api/public --grpc-gateway_out=logtostderr=true:./pkg/api/public ./api/public/public.proto
|
||||||
protoc -I ./api/private --go_out=plugins=grpc:./internal/api/private ./api/private/private.proto
|
protoc -I ./api/private --go_out=plugins=grpc:./internal/api/private ./api/private/private.proto
|
||||||
|
|
||||||
compose-build:
|
up: sup-up calendar-up sender-up sheduler-up
|
||||||
sudo -S docker-compose -f ./cicd/docker-compose.yml build
|
|
||||||
|
|
||||||
up:
|
down: calendar-down sender-down sheduler-down sup-down clean
|
||||||
sudo -S docker-compose -f ./cicd/docker-compose.yml up -d --build
|
|
||||||
|
|
||||||
down: shutdown clean
|
calendar-up:
|
||||||
|
docker-compose -f ./cicd/dc_calendar.yml up -d --build
|
||||||
|
calendar-down:
|
||||||
|
docker-compose -f ./cicd/dc_calendar.yml down
|
||||||
|
|
||||||
shutdown:
|
sender-up:
|
||||||
sudo -S docker-compose -f ./cicd/docker-compose.yml down
|
docker-compose -f ./cicd/dc_sender.yml up -d --build
|
||||||
|
sender-down:
|
||||||
|
docker-compose -f ./cicd/dc_sender.yml down
|
||||||
|
|
||||||
|
sheduler-up:
|
||||||
|
docker-compose -f ./cicd/dc_sheduler.yml up -d --build
|
||||||
|
sheduler-down:
|
||||||
|
docker-compose -f ./cicd/dc_sheduler.yml down
|
||||||
|
|
||||||
|
sup-up:
|
||||||
|
docker-compose -f ./cicd/dc_sup.yml up -d --build
|
||||||
|
sup-down:
|
||||||
|
docker-compose -f ./cicd/dc_sup.yml down
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
sudo docker rmi $(sudo docker images | grep '<none>' | awk '{print $3}')
|
sudo docker rmi $(sudo docker images | grep '<none>' | awk '{print $3}')
|
||||||
|
|
||||||
calendar-start:
|
|
||||||
nohup ./bin/calendar -config ./configs/calendar.conf > /dev/null 2>&1 &
|
|
||||||
calendar-stop:
|
|
||||||
kill -9 `pgrep calendar`
|
|
||||||
|
|
||||||
scheduler-start:
|
|
||||||
nohup ./bin/scheduler -config ./configs/scheduler.conf > /dev/null 2>&1 &
|
|
||||||
scheduler-stop:
|
|
||||||
kill -9 `pgrep scheduler`
|
|
||||||
|
|
||||||
sender-start:
|
|
||||||
nohup ./bin/sender -config ./configs/sender.conf > /dev/null 2>&1 &
|
|
||||||
sender-stop:
|
|
||||||
kill -9 `pgrep sender`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: build run test lint
|
.PHONY: build run test lint
|
@ -6,20 +6,9 @@ RUN go get -d ./cmd/calendar/.
|
|||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o calendar ./cmd/calendar/.
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o calendar ./cmd/calendar/.
|
||||||
|
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
ENV APP_GRPC_ADDRESS=0.0.0.0
|
ENV APP_GRPC_PORT $APP_GRPC_PORT
|
||||||
ENV APP_GRPC_PORT=50051
|
ENV APP_HTTP_PORT $APP_HTTP_PORT
|
||||||
ENV APP_HTTP_ADDRESS=0.0.0.0
|
ENV APP_API_PORT $APP_API_PORT
|
||||||
ENV APP_HTTP_PORT=8888
|
|
||||||
ENV APP_API_ADDRESS=0.0.0.0
|
|
||||||
ENV APP_API_PORT=50053
|
|
||||||
ENV APP_LOGGER_FILE=/logs/calendar.log
|
|
||||||
ENV APP_LOGGER_LEVEL=INFO
|
|
||||||
ENV APP_STORAGE_INMEMORY=false
|
|
||||||
ENV APP_STORAGE_SQLHOST=psql
|
|
||||||
ENV APP_STORAGE_SQLPORT=5432
|
|
||||||
ENV APP_STORAGE_SQLDBASE=calendar
|
|
||||||
ENV APP_STORAGE_SQLUSER=calendar
|
|
||||||
ENV APP_STORAGE_SQLPASS=12345678
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=builder /app/calendar ./sbin
|
COPY --from=builder /app/calendar ./sbin
|
||||||
EXPOSE ${APP_GRPC_PORT}
|
EXPOSE ${APP_GRPC_PORT}
|
||||||
|
29
hw12_13_14_15_calendar/cicd/dc_calendar.yml
Normal file
29
hw12_13_14_15_calendar/cicd/dc_calendar.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
calendar:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: ./cicd/calendar/Dockerfile
|
||||||
|
volumes:
|
||||||
|
- ../logs:/logs
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
APP_GRPC_ADDRESS: 0.0.0.0
|
||||||
|
APP_GRPC_PORT: 50051
|
||||||
|
APP_HTTP_ADDRESS: 0.0.0.0
|
||||||
|
APP_HTTP_PORT: 8888
|
||||||
|
APP_API_ADDRESS: 0.0.0.0
|
||||||
|
APP_API_PORT: 50053
|
||||||
|
APP_LOGGER_FILE: /logs/calendar.log
|
||||||
|
APP_LOGGER_LEVEL: INFO
|
||||||
|
APP_STORAGE_INMEMORY: "false"
|
||||||
|
APP_STORAGE_SQLHOST: localhost
|
||||||
|
APP_STORAGE_SQLPORT: 5432
|
||||||
|
APP_STORAGE_SQLDBASE: calendar
|
||||||
|
APP_STORAGE_SQLUSER: calendar
|
||||||
|
APP_STORAGE_SQLPASS: 12345678
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
- 50051:50051
|
||||||
|
- 50053:50053
|
||||||
|
network_mode: host
|
20
hw12_13_14_15_calendar/cicd/dc_sender.yml
Normal file
20
hw12_13_14_15_calendar/cicd/dc_sender.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
sender:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: ./cicd/sender/Dockerfile
|
||||||
|
volumes:
|
||||||
|
- ../logs:/logs
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
APP_RABBITMQ_ADDRESS: localhost
|
||||||
|
APP_RABBITMQ_PORT: 5672
|
||||||
|
APP_RABBITMQ_LOGIN: rabbit
|
||||||
|
APP_RABBITMQ_PASS: rabbit
|
||||||
|
APP_RABBITMQ_EXCHANGE: calendar
|
||||||
|
APP_RABBITMQ_QUEUE: notifications
|
||||||
|
APP_RABBITMQ_KEY: events
|
||||||
|
APP_LOGGER_FILE: /logs/calendar.log
|
||||||
|
APP_LOGGER_LEVEL: INFO
|
||||||
|
network_mode: host
|
22
hw12_13_14_15_calendar/cicd/dc_sheduler.yml
Normal file
22
hw12_13_14_15_calendar/cicd/dc_sheduler.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
scheduler:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: ./cicd/scheduler/Dockerfile
|
||||||
|
volumes:
|
||||||
|
- ../logs:/logs
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
APP_RABBITMQ_ADDRESS: localhost
|
||||||
|
APP_RABBITMQ_PORT: 5672
|
||||||
|
APP_RABBITMQ_LOGIN: rabbit
|
||||||
|
APP_RABBITMQ_PASS: rabbit
|
||||||
|
APP_RABBITMQ_EXCHANGE: calendar
|
||||||
|
APP_RABBITMQ_QUEUE: notifications
|
||||||
|
APP_RABBITMQ_KEY: events
|
||||||
|
APP_API_ADDRESS: localhost
|
||||||
|
APP_API_PORT: 50053
|
||||||
|
APP_LOGGER_FILE: /logs/calendar.log
|
||||||
|
APP_LOGGER_LEVEL: INFO
|
||||||
|
network_mode: host
|
39
hw12_13_14_15_calendar/cicd/dc_sup.yml
Normal file
39
hw12_13_14_15_calendar/cicd/dc_sup.yml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
goose:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: ./cicd/goose/Dockerfile
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
GOOSE_DRIVER: "postgres"
|
||||||
|
GOOSE_DBSTRING: "host=localhost port=5432 user=calendar password=12345678 dbname=calendar sslmode=disable"
|
||||||
|
depends_on:
|
||||||
|
- psql
|
||||||
|
network_mode: host
|
||||||
|
|
||||||
|
psql:
|
||||||
|
image: postgres:11-alpine
|
||||||
|
hostname: "psql"
|
||||||
|
container_name: psql
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: calendar
|
||||||
|
POSTGRES_PASSWORD: 12345678
|
||||||
|
POSTGRES_DB: calendar
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
network_mode: host
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
image: rabbitmq:3-management-alpine
|
||||||
|
hostname: "rabbitmq"
|
||||||
|
container_name: rabbitmq
|
||||||
|
environment:
|
||||||
|
RABBITMQ_ERLANG_COOKIE: "SWQOKODSQALRPCLNMEQG"
|
||||||
|
RABBITMQ_DEFAULT_USER: "rabbit"
|
||||||
|
RABBITMQ_DEFAULT_PASS: "rabbit"
|
||||||
|
RABBITMQ_DEFAULT_VHOST: "/"
|
||||||
|
ports:
|
||||||
|
- 15672:15672
|
||||||
|
- 5672:5672
|
||||||
|
network_mode: host
|
@ -1,80 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
services:
|
|
||||||
calendar:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: ./cicd/calendar/Dockerfile
|
|
||||||
volumes:
|
|
||||||
- ../logs:/logs
|
|
||||||
ports:
|
|
||||||
- "8888:8888"
|
|
||||||
- "50051:50051"
|
|
||||||
- "50053:50053"
|
|
||||||
expose:
|
|
||||||
- 8888
|
|
||||||
- 50051
|
|
||||||
- 50053
|
|
||||||
depends_on:
|
|
||||||
- psql
|
|
||||||
- goose
|
|
||||||
|
|
||||||
scheduler:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: ./cicd/scheduler/Dockerfile
|
|
||||||
volumes:
|
|
||||||
- ../logs:/logs
|
|
||||||
depends_on:
|
|
||||||
- rabbitmq
|
|
||||||
- calendar
|
|
||||||
restart: on-failure
|
|
||||||
|
|
||||||
sender:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: ./cicd/sender/Dockerfile
|
|
||||||
volumes:
|
|
||||||
- ../logs:/logs
|
|
||||||
depends_on:
|
|
||||||
- rabbitmq
|
|
||||||
restart: on-failure
|
|
||||||
|
|
||||||
goose:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: ./cicd/goose/Dockerfile
|
|
||||||
environment:
|
|
||||||
GOOSE_DRIVER: "postgres"
|
|
||||||
GOOSE_DBSTRING: "host=psql port=5432 user=calendar password=12345678 dbname=calendar sslmode=disable"
|
|
||||||
depends_on:
|
|
||||||
- psql
|
|
||||||
restart: on-failure
|
|
||||||
|
|
||||||
psql:
|
|
||||||
image: postgres:11-alpine
|
|
||||||
hostname: "psql"
|
|
||||||
container_name: psql
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: calendar
|
|
||||||
POSTGRES_PASSWORD: 12345678
|
|
||||||
POSTGRES_DB: calendar
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
expose:
|
|
||||||
- 5432
|
|
||||||
|
|
||||||
rabbitmq:
|
|
||||||
image: rabbitmq:3-management-alpine
|
|
||||||
hostname: "rabbitmq"
|
|
||||||
container_name: rabbitmq
|
|
||||||
environment:
|
|
||||||
RABBITMQ_ERLANG_COOKIE: "SWQOKODSQALRPCLNMEQG"
|
|
||||||
RABBITMQ_DEFAULT_USER: "rabbit"
|
|
||||||
RABBITMQ_DEFAULT_PASS: "rabbit"
|
|
||||||
RABBITMQ_DEFAULT_VHOST: "/"
|
|
||||||
ports:
|
|
||||||
- "5672:5672"
|
|
||||||
- "15672:15672"
|
|
||||||
expose:
|
|
||||||
- 15672
|
|
||||||
- 5672
|
|
@ -6,17 +6,6 @@ RUN go get -d ./cmd/scheduler/.
|
|||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o scheduler ./cmd/scheduler/.
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o scheduler ./cmd/scheduler/.
|
||||||
|
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
ENV APP_RABBITMQ_ADDRESS=rabbitmq
|
|
||||||
ENV APP_RABBITMQ_PORT=5672
|
|
||||||
ENV APP_RABBITMQ_LOGIN=rabbit
|
|
||||||
ENV APP_RABBITMQ_PASS=rabbit
|
|
||||||
ENV APP_RABBITMQ_EXCHANGE=calendar
|
|
||||||
ENV APP_RABBITMQ_QUEUE=notifications
|
|
||||||
ENV APP_RABBITMQ_KEY=events
|
|
||||||
ENV APP_API_ADDRESS=calendar
|
|
||||||
ENV APP_API_PORT=50053
|
|
||||||
ENV APP_LOGGER_FILE=/logs/calendar.log
|
|
||||||
ENV APP_LOGGER_LEVEL=INFO
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=builder /app/scheduler ./sbin
|
COPY --from=builder /app/scheduler ./sbin
|
||||||
ENTRYPOINT ["scheduler"]
|
ENTRYPOINT ["scheduler"]
|
||||||
|
@ -6,15 +6,6 @@ RUN go get -d ./cmd/sender/.
|
|||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o sender ./cmd/sender/.
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o sender ./cmd/sender/.
|
||||||
|
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
ENV APP_RABBITMQ_ADDRESS=rabbitmq
|
|
||||||
ENV APP_RABBITMQ_PORT=5672
|
|
||||||
ENV APP_RABBITMQ_LOGIN=rabbit
|
|
||||||
ENV APP_RABBITMQ_PASS=rabbit
|
|
||||||
ENV APP_RABBITMQ_EXCHANGE=calendar
|
|
||||||
ENV APP_RABBITMQ_QUEUE=notifications
|
|
||||||
ENV APP_RABBITMQ_KEY=events
|
|
||||||
ENV APP_LOGGER_FILE=/logs/calendar.log
|
|
||||||
ENV APP_LOGGER_LEVEL=INFO
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=builder /app/sender ./sbin
|
COPY --from=builder /app/sender ./sbin
|
||||||
ENTRYPOINT ["sender"]
|
ENTRYPOINT ["sender"]
|
||||||
|
@ -15,7 +15,7 @@ File = "./logs/calendar.log"
|
|||||||
Level = "INFO"
|
Level = "INFO"
|
||||||
|
|
||||||
[Storage]
|
[Storage]
|
||||||
inMemory = true
|
inMemory = false
|
||||||
SQLHost = "localhost"
|
SQLHost = "localhost"
|
||||||
SQLPort = "5432"
|
SQLPort = "5432"
|
||||||
SQLDbase = "calendar"
|
SQLDbase = "calendar"
|
||||||
|
@ -9,16 +9,12 @@ require (
|
|||||||
github.com/golang/protobuf v1.4.2
|
github.com/golang/protobuf v1.4.2
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.15.0
|
github.com/grpc-ecosystem/grpc-gateway v1.15.0
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/lib/pq v1.8.0 // indirect
|
github.com/lib/pq v1.10.0
|
||||||
github.com/mattn/go-sqlite3 v1.14.5 // indirect
|
|
||||||
github.com/mxschmitt/golang-env-struct v0.0.0-20181017075525-0c54aeca8397
|
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pressly/goose v2.6.0+incompatible // indirect
|
|
||||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
github.com/sirupsen/logrus v1.4.2 // indirect
|
||||||
github.com/streadway/amqp v1.0.0
|
github.com/streadway/amqp v1.0.0
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/ziutek/mymysql v1.5.4 // indirect
|
|
||||||
go.uber.org/zap v1.15.0 // indirect
|
go.uber.org/zap v1.15.0 // indirect
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344
|
||||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
|
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
|
||||||
|
@ -54,12 +54,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
|
||||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
|
||||||
github.com/mxschmitt/golang-env-struct v0.0.0-20181017075525-0c54aeca8397 h1:fbcg7+DIrrjxSsS78ARgJu/qZOO928w4mCj1KBEO7xM=
|
|
||||||
github.com/mxschmitt/golang-env-struct v0.0.0-20181017075525-0c54aeca8397/go.mod h1:BvJngicNxsNmAUzt7zXpaoWKwuBiyxnD7DxzxfrrPyY=
|
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
@ -68,8 +64,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pressly/goose v2.6.0+incompatible h1:3f8zIQ8rfgP9tyI0Hmcs2YNAqUCL1c+diLe3iU8Qd/k=
|
|
||||||
github.com/pressly/goose v2.6.0+incompatible/go.mod h1:m+QHWCqxR3k8D9l7qfzuC/djtlfzxr34mozWDYEu1z8=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||||
@ -90,8 +84,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
|
||||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
@ -24,11 +24,6 @@ func New(logger logger.Interface, storage store.StorageInterface) *App {
|
|||||||
return &App{Logger: logger, Storage: storage}
|
return &App{Logger: logger, Storage: storage}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Handler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(200)
|
|
||||||
_, _ = w.Write([]byte("Hello! I'm calendar app!"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) LoggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
func (a *App) LoggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
CREATE TABLE events (
|
CREATE TABLE events (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
title varchar(255) NOT NULL,
|
title varchar(255) NOT NULL,
|
||||||
date timestamptz NOT NULL,
|
date timestamp NOT NULL,
|
||||||
latency int8 NOT NULL,
|
latency int8 NOT NULL,
|
||||||
note text NULL,
|
note text NULL,
|
||||||
userID int8 NOT NULL,
|
userID int8 NOT NULL,
|
||||||
notifyTime timestamptz NULL,
|
notifyTime int8 NULL,
|
||||||
notified bool
|
notified bool
|
||||||
);
|
);
|
||||||
-- +goose StatementEnd
|
-- +goose StatementEnd
|
||||||
|
@ -3,12 +3,15 @@ package sql
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
|
||||||
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/storage/event"
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/storage/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dateTimeLayout = "2006-01-02 15:04:00 -0700"
|
const dateTimeLayout = "2006-01-02T15:04:00Z"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
User string
|
User string
|
||||||
@ -22,17 +25,12 @@ type Storage struct {
|
|||||||
db *sql.DB
|
db *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(conf Config) *Storage {
|
func New(config Config) *Storage {
|
||||||
return &Storage{}
|
db, err := sql.Open("postgres", "user="+config.User+" password="+config.Pass+" host="+config.Host+" port="+config.Port+" dbname="+config.Dbase+" sslmode=disable")
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Storage) Connect(config Config) error {
|
|
||||||
var err error
|
|
||||||
s.db, err = sql.Open("mysql", config.User+":"+config.Pass+"@tcp("+config.Host+":"+config.Port+")/"+config.Dbase)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't connect to SQL server: %w", err)
|
log.Fatalf("can't connect to db: %s",err.Error())
|
||||||
}
|
}
|
||||||
return nil
|
return &Storage{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Storage) Close() error {
|
func (s *Storage) Close() error {
|
||||||
@ -40,25 +38,21 @@ func (s *Storage) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Storage) Create(ev event.Event) (event.ID, error) {
|
func (s *Storage) Create(ev event.Event) (event.ID, error) {
|
||||||
res, err := s.db.Exec(
|
lastInsertId := -1
|
||||||
|
if err := s.db.QueryRow(
|
||||||
`INSERT INTO events
|
`INSERT INTO events
|
||||||
(title, date, latency, note, userID, notifyTime) VALUES
|
(title, date, latency, note, userID, notifyTime) VALUES
|
||||||
($1, $2, $3, $4, $5, $6)`,
|
($1, $2, $3, $4, $5, $6) RETURNING id`,
|
||||||
ev.Title,
|
ev.Title,
|
||||||
ev.Date.Format(dateTimeLayout),
|
ev.Date.Format(dateTimeLayout),
|
||||||
ev.Latency,
|
ev.Latency,
|
||||||
ev.Note,
|
ev.Note,
|
||||||
ev.UserID,
|
ev.UserID,
|
||||||
ev.NotifyTime,
|
ev.NotifyTime,
|
||||||
)
|
).Scan(&lastInsertId); err != nil {
|
||||||
if err != nil {
|
|
||||||
return -1, fmt.Errorf("can't create event in SQL DB: %w", err)
|
return -1, fmt.Errorf("can't create event in SQL DB: %w", err)
|
||||||
}
|
}
|
||||||
idint64, err := res.LastInsertId()
|
return event.ID(lastInsertId), nil
|
||||||
if err != nil {
|
|
||||||
return -1, fmt.Errorf("can't get LastInsertId from SQL DB: %w", err)
|
|
||||||
}
|
|
||||||
return event.ID(idint64), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Storage) Update(id event.ID, event event.Event) error {
|
func (s *Storage) Update(id event.ID, event event.Event) error {
|
||||||
@ -93,7 +87,7 @@ func (s *Storage) Delete(id event.ID) error {
|
|||||||
|
|
||||||
func (s *Storage) List() (map[event.ID]event.Event, error) {
|
func (s *Storage) List() (map[event.ID]event.Event, error) {
|
||||||
res := make(map[event.ID]event.Event)
|
res := make(map[event.ID]event.Event)
|
||||||
results, err := s.db.Query(`SELECT (id,title,date,latency,note,userID,notifyTime) from events ORDER BY id`)
|
results, err := s.db.Query(`SELECT id,title,date,latency,note,userID,notifyTime from events ORDER BY id`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get list of events from SQL DB: %w", err)
|
return nil, fmt.Errorf("can't get list of events from SQL DB: %w", err)
|
||||||
}
|
}
|
||||||
@ -122,7 +116,7 @@ func (s *Storage) GetByID(id event.ID) (event.Event, bool) {
|
|||||||
var res event.Event
|
var res event.Event
|
||||||
var dateRaw string
|
var dateRaw string
|
||||||
err := s.db.QueryRow(
|
err := s.db.QueryRow(
|
||||||
`SELECT (id,title,date,latency,note,userID,notifyTime) from events where id=$1`, id).Scan(res.Title, dateRaw, res.Latency, res.Note, res.UserID, res.NotifyTime)
|
`SELECT title,date,latency,note,userID,notifyTime from events where id=$1`, id).Scan(&res.Title, &dateRaw, &res.Latency, &res.Note, &res.UserID, &res.NotifyTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, false
|
return res, false
|
||||||
}
|
}
|
||||||
@ -136,15 +130,16 @@ func (s *Storage) GetByID(id event.ID) (event.Event, bool) {
|
|||||||
|
|
||||||
func (s *Storage) GetByDate(startDate time.Time, rng string) (map[event.ID]event.Event, error) {
|
func (s *Storage) GetByDate(startDate time.Time, rng string) (map[event.ID]event.Event, error) {
|
||||||
res := make(map[event.ID]event.Event)
|
res := make(map[event.ID]event.Event)
|
||||||
|
endDate := getEndDate(startDate, rng)
|
||||||
|
|
||||||
results, err := s.db.Query(
|
results, err := s.db.Query(
|
||||||
`SELECT (id,title,date,latency,note,userID,notifyTime)
|
`SELECT id,title,date,latency,note,userID,notifyTime
|
||||||
from events
|
from events
|
||||||
where (date>$1 AND date<$2) OR
|
where (date>=$1 AND date<=$2)
|
||||||
(date+latency>$1 AND date+latency<$2) OR
|
|
||||||
(date<$1 AND date+latency>$2)
|
|
||||||
ORDER BY id`,
|
ORDER BY id`,
|
||||||
startDate,
|
startDate.Format(dateTimeLayout),
|
||||||
getEndDate(startDate, rng))
|
endDate.Format(dateTimeLayout))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get list of events from SQL DB: %w", err)
|
return nil, fmt.Errorf("can't get list of events from SQL DB: %w", err)
|
||||||
}
|
}
|
||||||
|
97
hw12_13_14_15_calendar/test/client/grpcapi.go
Normal file
97
hw12_13_14_15_calendar/test/client/grpcapi.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GRPCAPI struct{
|
||||||
|
Name string
|
||||||
|
Ctx context.Context
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) GetName() string {
|
||||||
|
return h.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) Create(req *public.CreateReq) (*public.CreateRsp, error) {
|
||||||
|
ctx, cliGRPC, err := getCli(h)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cliGRPC.Create(ctx, req)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) Update(req *public.UpdateReq) error {
|
||||||
|
ctx, cliGRPC, err := getCli(h)
|
||||||
|
if err != nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = cliGRPC.Update(ctx, req)
|
||||||
|
if err != nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) Delete(req *public.DeleteReq) error {
|
||||||
|
ctx, cliGRPC, err := getCli(h)
|
||||||
|
if err != nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = cliGRPC.Delete(ctx, req)
|
||||||
|
if err != nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) GetByID(req *public.GetByIDReq) (*public.GetByIDResp, error) {
|
||||||
|
ctx, cliGRPC, err := getCli(h)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cliGRPC.GetByID(ctx, req)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) List() (*public.ListResp, error) {
|
||||||
|
ctx, cliGRPC, err := getCli(h)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cliGRPC.List(ctx, &empty.Empty{})
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GRPCAPI) GetByDate(req *public.GetByDateReq) (*public.GetByDateResp, error) {
|
||||||
|
ctx, cliGRPC, err := getCli(h)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cliGRPC.GetByDate(ctx, req)
|
||||||
|
if err != nil{
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCli(h GRPCAPI) (context.Context, public.GrpcClient, error) {
|
||||||
|
ctx,_ := context.WithTimeout(h.Ctx, 15*time.Second)
|
||||||
|
cliGRPC, err := public.NewClient(ctx,h.Host, h.Port)
|
||||||
|
return ctx, cliGRPC, err
|
||||||
|
}
|
150
hw12_13_14_15_calendar/test/client/httpapi.go
Normal file
150
hw12_13_14_15_calendar/test/client/httpapi.go
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HTTPAPI struct{
|
||||||
|
Name string
|
||||||
|
BaseURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) GetName() string {
|
||||||
|
return h.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) Create(req *public.CreateReq) (*public.CreateRsp, error) {
|
||||||
|
jreq,err:= json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return &public.CreateRsp{}, err
|
||||||
|
}
|
||||||
|
res, body, err := apiCall("POST",h.BaseURL+"/events", jreq)
|
||||||
|
if err != nil {
|
||||||
|
return &public.CreateRsp{}, err
|
||||||
|
}
|
||||||
|
if res.StatusCode!=201 {
|
||||||
|
return &public.CreateRsp{}, fmt.Errorf("unexpected status code %d",res.StatusCode)
|
||||||
|
}
|
||||||
|
var createRsp public.CreateRsp
|
||||||
|
err = json.Unmarshal(body,&createRsp)
|
||||||
|
if err != nil {
|
||||||
|
return &public.CreateRsp{}, err
|
||||||
|
}
|
||||||
|
return &createRsp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) Update(req *public.UpdateReq) error {
|
||||||
|
jreq, err:= json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res, _, err := apiCall("PUT",h.BaseURL+"/events/"+strconv.Itoa(int(req.ID)), jreq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.StatusCode!=201 {
|
||||||
|
return fmt.Errorf("unexpected status code %d",res.StatusCode)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) Delete(req *public.DeleteReq) error {
|
||||||
|
jreq, err:= json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res, _, err := apiCall("DELETE",h.BaseURL+"/events/"+strconv.Itoa(int(req.ID)), jreq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.StatusCode!=201 {
|
||||||
|
return fmt.Errorf("unexpected status code %d",res.StatusCode)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) GetByID(req *public.GetByIDReq) ( *public.GetByIDResp, error) {
|
||||||
|
jreq, err:= json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return &public.GetByIDResp{}, err
|
||||||
|
}
|
||||||
|
res, body, err := apiCall("GET",h.BaseURL+"/events/"+strconv.Itoa(int(req.ID)), jreq)
|
||||||
|
if err != nil {
|
||||||
|
return &public.GetByIDResp{}, err
|
||||||
|
}
|
||||||
|
if res.StatusCode!=201 {
|
||||||
|
return &public.GetByIDResp{}, fmt.Errorf("unexpected status code %d",res.StatusCode)
|
||||||
|
}
|
||||||
|
var getByIDResp public.GetByIDResp
|
||||||
|
err = json.Unmarshal(body,&getByIDResp)
|
||||||
|
if err != nil {
|
||||||
|
return &public.GetByIDResp{}, err
|
||||||
|
}
|
||||||
|
return &getByIDResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) List() ( *public.ListResp, error) {
|
||||||
|
res, body, err := apiCall("GET",h.BaseURL+"/events", nil)
|
||||||
|
if err != nil {
|
||||||
|
return &public.ListResp{}, err
|
||||||
|
}
|
||||||
|
if res.StatusCode!=200 {
|
||||||
|
return &public.ListResp{}, fmt.Errorf("unexpected status code %d",res.StatusCode)
|
||||||
|
}
|
||||||
|
var listResp public.ListResp
|
||||||
|
err = json.Unmarshal(body,&listResp)
|
||||||
|
if err != nil {
|
||||||
|
return &public.ListResp{}, err
|
||||||
|
}
|
||||||
|
return &listResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HTTPAPI) GetByDate(req *public.GetByDateReq) ( *public.GetByDateResp, error) {
|
||||||
|
jreq, err:= json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return &public.GetByDateResp{}, err
|
||||||
|
}
|
||||||
|
res, body, err := apiCall("GET",h.BaseURL+"/events/"+string(req.Range)+"/"+req.Date.String(), jreq)
|
||||||
|
if err != nil {
|
||||||
|
return &public.GetByDateResp{}, err
|
||||||
|
}
|
||||||
|
if res.StatusCode!=201 {
|
||||||
|
return &public.GetByDateResp{}, fmt.Errorf("unexpected status code %d",res.StatusCode)
|
||||||
|
}
|
||||||
|
var getByDateResp public.GetByDateResp
|
||||||
|
err = json.Unmarshal(body,&getByDateResp)
|
||||||
|
if err != nil {
|
||||||
|
return &public.GetByDateResp{}, err
|
||||||
|
}
|
||||||
|
return &getByDateResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func apiCall(method string, url string, payload []byte) (*http.Response, []byte, error) {
|
||||||
|
client := &http.Client{Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: 15*time.Second}).DialContext }}
|
||||||
|
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
req.Close = true
|
||||||
|
res, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err = res.Body.Close(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return res, body, nil
|
||||||
|
}
|
13
hw12_13_14_15_calendar/test/client/iface.go
Normal file
13
hw12_13_14_15_calendar/test/client/iface.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public"
|
||||||
|
|
||||||
|
type Interface interface {
|
||||||
|
GetName() string
|
||||||
|
Create(req *public.CreateReq) (*public.CreateRsp, error)
|
||||||
|
Update(req *public.UpdateReq) error
|
||||||
|
Delete(req *public.DeleteReq) error
|
||||||
|
GetByID(req *public.GetByIDReq) (*public.GetByIDResp, error)
|
||||||
|
List() (*public.ListResp, error)
|
||||||
|
GetByDate(req *public.GetByDateReq) (*public.GetByDateResp, error)
|
||||||
|
}
|
@ -1,244 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"github.com/golang/protobuf/ptypes"
|
|
||||||
"github.com/golang/protobuf/ptypes/duration"
|
|
||||||
"github.com/golang/protobuf/ptypes/empty"
|
|
||||||
"github.com/golang/protobuf/ptypes/timestamp"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public"
|
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var testEvent01 = public.CreateReq{
|
|
||||||
Title: "Test event 01",
|
|
||||||
Date: time2pbtimestamp(time.Now().Add(30 * time.Second)),
|
|
||||||
Latency: dur2pbduration(24 * time.Hour),
|
|
||||||
Note: "Note of test event 01",
|
|
||||||
NotifyTime: dur2pbduration(5 * time.Minute),
|
|
||||||
UserID: 1111,
|
|
||||||
}
|
|
||||||
|
|
||||||
var testEvent02 = public.CreateReq{
|
|
||||||
Title: "Test event 02",
|
|
||||||
Date: time2pbtimestamp(time.Now().Add(60 * time.Second)),
|
|
||||||
Latency: dur2pbduration(2 * 24 * time.Hour),
|
|
||||||
Note: "Note of test event 02",
|
|
||||||
NotifyTime: dur2pbduration(5 * time.Minute),
|
|
||||||
UserID: 2222,
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := TestPublicAPIEndpoint(); err != nil {
|
log.Fatalln("Nothing to do")
|
||||||
log.Fatalf("TestPublicAPIEndpoint FAIL: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := TestPublicGRPCEndpoint(); err != nil {
|
|
||||||
log.Fatalf("TestPublicGRPCEndpoint FAIL: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPublicGRPCEndpoint() error {
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
publicAPI, err := public.NewClient(ctx, "localhost", "50051")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Add(5)
|
|
||||||
// Реализовать тесты логики приложения:
|
|
||||||
t.Run("test public GRPC.Create and GRPC.GetById", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, resp1.ID, int64(0))
|
|
||||||
|
|
||||||
resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, 1, len(resp2.Events))
|
|
||||||
require.Equal(t, testEvent01.Title, resp2.Events[0].Title)
|
|
||||||
require.Equal(t, testEvent01.UserID, resp2.Events[0].UserID)
|
|
||||||
require.Equal(t, testEvent01.Date.Seconds, resp2.Events[0].Date.Seconds)
|
|
||||||
require.Equal(t, testEvent01.Note, resp2.Events[0].Note)
|
|
||||||
})
|
|
||||||
t.Run("test public GRPC.Create, GRPC.Update and GRPC.GetById", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, resp1.ID, int64(0))
|
|
||||||
_, err = publicAPI.Update(ctx, &public.UpdateReq{ID: resp1.ID, Event: &public.Event{ID: resp1.ID, Title: testEvent02.Title, Date: testEvent02.Date, Latency: testEvent02.Latency, Note: testEvent02.Note, UserID: testEvent02.UserID, NotifyTime: testEvent02.NotifyTime}})
|
|
||||||
require.NoError(t, err)
|
|
||||||
resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, 1, len(resp2.Events))
|
|
||||||
require.Equal(t, testEvent02.Title, resp2.Events[0].Title)
|
|
||||||
require.Equal(t, testEvent02.UserID, resp2.Events[0].UserID)
|
|
||||||
require.Equal(t, testEvent02.Date.Seconds, resp2.Events[0].Date.Seconds)
|
|
||||||
require.Equal(t, testEvent02.Note, resp2.Events[0].Note)
|
|
||||||
})
|
|
||||||
t.Run("test public GRPC.Create, GRPC.Delete and GRPC.GetById", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, resp1.ID, int64(0))
|
|
||||||
_, err = publicAPI.Delete(ctx, &public.DeleteReq{ID: resp1.ID})
|
|
||||||
require.NoError(t, err)
|
|
||||||
resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID})
|
|
||||||
require.Error(t, err)
|
|
||||||
require.Nil(t, resp2)
|
|
||||||
})
|
|
||||||
t.Run("test public GRPC.Create and GRPC.List", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
resp2, err := publicAPI.Create(ctx, &testEvent02)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotEqual(t, resp1.ID, resp2.ID)
|
|
||||||
|
|
||||||
list, err := publicAPI.List(ctx, &empty.Empty{})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.GreaterOrEqual(t, len(list.Events), 2)
|
|
||||||
var e1, e2 bool
|
|
||||||
for _, v := range list.Events {
|
|
||||||
if v.ID == resp1.ID {
|
|
||||||
e1 = true
|
|
||||||
}
|
|
||||||
if v.ID == resp2.ID {
|
|
||||||
e2 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.True(t, e1)
|
|
||||||
require.True(t, e2)
|
|
||||||
})
|
|
||||||
t.Run("test public GRPC.Create and GRPC.GetByDate", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
list, err := publicAPI.GetByDate(ctx, &public.GetByDateReq{Date: testEvent01.Date, Range: public.QueryRange_DAY})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.GreaterOrEqual(t, len(list.Events), 2)
|
|
||||||
var e1 bool
|
|
||||||
for _, v := range list.Events {
|
|
||||||
if v.ID == resp1.ID {
|
|
||||||
e1 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.True(t, e1)
|
|
||||||
})
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPublicAPIEndpoint() error {
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
publicAPI, err := public.NewClient(ctx, "localhost", "50051")
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
wg.Add(5)
|
|
||||||
// Реализовать тесты логики приложения:
|
|
||||||
t.Run("test public GRPC.Create and GRPC.GetById", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, resp1.ID, int64(0))
|
|
||||||
|
|
||||||
resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, 1, len(resp2.Events))
|
|
||||||
require.Equal(t, testEvent01.Title, resp2.Events[0].Title)
|
|
||||||
require.Equal(t, testEvent01.UserID, resp2.Events[0].UserID)
|
|
||||||
require.Equal(t, testEvent01.Date.Seconds, resp2.Events[0].Date.Seconds)
|
|
||||||
require.Equal(t, testEvent01.Note, resp2.Events[0].Note)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("test public GRPC.Create, GRPC.Update and GRPC.GetById", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, resp1.ID, int64(0))
|
|
||||||
_, err = publicAPI.Update(ctx, &public.UpdateReq{ID: resp1.ID, Event: &public.Event{ID: resp1.ID, Title: testEvent02.Title, Date: testEvent02.Date, Latency: testEvent02.Latency, Note: testEvent02.Note, UserID: testEvent02.UserID, NotifyTime: testEvent02.NotifyTime}})
|
|
||||||
require.NoError(t, err)
|
|
||||||
resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, 1, len(resp2.Events))
|
|
||||||
require.Equal(t, testEvent02.Title, resp2.Events[0].Title)
|
|
||||||
require.Equal(t, testEvent02.UserID, resp2.Events[0].UserID)
|
|
||||||
require.Equal(t, testEvent02.Date.Seconds, resp2.Events[0].Date.Seconds)
|
|
||||||
require.Equal(t, testEvent02.Note, resp2.Events[0].Note)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("test public GRPC.Create, GRPC.Delete and GRPC.GetById", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, resp1.ID, int64(0))
|
|
||||||
_, err = publicAPI.Delete(ctx, &public.DeleteReq{ID: resp1.ID})
|
|
||||||
require.NoError(t, err)
|
|
||||||
resp2, err := publicAPI.GetByID(ctx, &public.GetByIDReq{ID: resp1.ID})
|
|
||||||
require.Error(t, err)
|
|
||||||
require.Nil(t, resp2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("test public GRPC.Create and GRPC.List", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
resp2, err := publicAPI.Create(ctx, &testEvent02)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotEqual(t, resp1.ID, resp2.ID)
|
|
||||||
|
|
||||||
list, err := publicAPI.List(ctx, &empty.Empty{})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.GreaterOrEqual(t, len(list.Events), 2)
|
|
||||||
var e1, e2 bool
|
|
||||||
for _, v := range list.Events {
|
|
||||||
if v.ID == resp1.ID {
|
|
||||||
e1 = true
|
|
||||||
}
|
|
||||||
if v.ID == resp2.ID {
|
|
||||||
e2 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.True(t, e1)
|
|
||||||
require.True(t, e2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("test public GRPC.Create and GRPC.GetByDate", func(t *testing.T) {
|
|
||||||
defer wg.Done()
|
|
||||||
resp1, err := publicAPI.Create(ctx, &testEvent01)
|
|
||||||
require.NoError(t, err)
|
|
||||||
list, err := publicAPI.GetByDate(ctx, &public.GetByDateReq{Date: testEvent01.Date, Range: public.QueryRange_DAY})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.GreaterOrEqual(t, len(list.Events), 2)
|
|
||||||
var e1 bool
|
|
||||||
for _, v := range list.Events {
|
|
||||||
if v.ID == resp1.ID {
|
|
||||||
e1 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.True(t, e1)
|
|
||||||
})
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func time2pbtimestamp(t time.Time) *timestamp.Timestamp {
|
|
||||||
r, err := ptypes.TimestampProto(t)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("cant convert Time to Timestamp: %s", err.Error())
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func dur2pbduration(t time.Duration) *duration.Duration {
|
|
||||||
return ptypes.DurationProto(t)
|
|
||||||
}
|
}
|
||||||
|
120
hw12_13_14_15_calendar/test/main_test.go
Normal file
120
hw12_13_14_15_calendar/test/main_test.go
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public"
|
||||||
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/test/client"
|
||||||
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/test/misc"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPublicAPIEndpoints(t *testing.T) {
|
||||||
|
cli := []client.Interface{
|
||||||
|
client.GRPCAPI{Ctx: context.Background(), Host: "localhost", Port:"50051", Name: "GRPC API"},
|
||||||
|
client.HTTPAPI{BaseURL: "http://localhost:50052", Name: "HTTP REST API"},
|
||||||
|
}
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
wg.Add(len(cli)*5)
|
||||||
|
|
||||||
|
for _,c := range cli {
|
||||||
|
t.Run("test "+c.GetName()+" for Create and GetById", func(t *testing.T) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
resp1, err := c.Create(&misc.TestEvent01)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp1.ID, int64(0))
|
||||||
|
|
||||||
|
resp2,err := c.GetByID(&public.GetByIDReq{ID:resp1.ID})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t,1, len(resp2.Events))
|
||||||
|
require.Equal(t, misc.TestEvent01.Title, resp2.Events[0].Title)
|
||||||
|
require.Equal(t, misc.TestEvent01.UserID, resp2.Events[0].UserID)
|
||||||
|
require.Equal(t, misc.TestEvent01.Note, resp2.Events[0].Note)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test "+c.GetName()+" for Create, Update and GetById", func(t *testing.T) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
resp1, err := c.Create(&misc.TestEvent01)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp1.ID, int64(0))
|
||||||
|
|
||||||
|
err = c.Update(&public.UpdateReq{ID:resp1.ID, Event: &public.Event{ ID: resp1.ID, Title: misc.TestEvent02.Title, Date: misc.TestEvent02.Date, Latency: misc.TestEvent02.Latency, Note: misc.TestEvent02.Note, UserID: misc.TestEvent02.UserID, NotifyTime: misc.TestEvent02.NotifyTime }})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
resp2,err := c.GetByID(&public.GetByIDReq{ID:resp1.ID})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t,1, len(resp2.Events))
|
||||||
|
require.Equal(t, misc.TestEvent02.Title, resp2.Events[0].Title)
|
||||||
|
require.Equal(t, misc.TestEvent02.UserID, resp2.Events[0].UserID)
|
||||||
|
require.Equal(t, misc.TestEvent02.Note, resp2.Events[0].Note)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test "+c.GetName()+" for Create, Delete and GetById", func(t *testing.T) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
resp1, err := c.Create(&misc.TestEvent01)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp1.ID, int64(0))
|
||||||
|
|
||||||
|
err = c.Delete(&public.DeleteReq{ ID: resp1.ID })
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
resp2,err := c.GetByID(&public.GetByIDReq{ID:resp1.ID})
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Nil(t, resp2)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test "+c.GetName()+" for Create and List", func(t *testing.T) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
resp1, err := c.Create(&misc.TestEvent01)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp1.ID, int64(0))
|
||||||
|
|
||||||
|
resp2, err := c.Create(&misc.TestEvent02)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp2.ID, int64(0))
|
||||||
|
|
||||||
|
resp3, err := c.List()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.GreaterOrEqual(t, len(resp3.Events), 2)
|
||||||
|
var e1, e2 bool
|
||||||
|
for _, v := range resp3.Events {
|
||||||
|
if v.ID == resp1.ID {
|
||||||
|
e1 = true
|
||||||
|
}
|
||||||
|
if v.ID == resp2.ID {
|
||||||
|
e2 = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.True(t, e1)
|
||||||
|
require.True(t, e2)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test "+c.GetName()+" for Create and GetByDate", func(t *testing.T) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
resp1, err := c.Create(&misc.TestEvent01)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp1.ID, int64(0))
|
||||||
|
|
||||||
|
resp2, err := c.Create(&misc.TestEvent02)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, resp2.ID, int64(0))
|
||||||
|
|
||||||
|
resp3,err := c.GetByDate(&public.GetByDateReq{Date: misc.TestEvent01.Date, Range: public.QueryRange_DAY})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.GreaterOrEqual(t, len(resp3.Events), 1)
|
||||||
|
var e1 bool
|
||||||
|
for _, v := range resp3.Events {
|
||||||
|
if v.ID == resp1.ID {
|
||||||
|
e1 = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.True(t, e1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
40
hw12_13_14_15_calendar/test/misc/misc.go
Normal file
40
hw12_13_14_15_calendar/test/misc/misc.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
"github.com/golang/protobuf/ptypes/duration"
|
||||||
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
|
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/pkg/api/public"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var TestEvent01 = public.CreateReq{
|
||||||
|
Title: "Test event 01",
|
||||||
|
Date: Time2pbtimestamp(time.Now().Add(30 * time.Second)),
|
||||||
|
Latency: Dur2pbduration(24 * time.Hour),
|
||||||
|
Note: "Note of test event 01",
|
||||||
|
NotifyTime: Dur2pbduration(5 * time.Minute),
|
||||||
|
UserID: 1111,
|
||||||
|
}
|
||||||
|
|
||||||
|
var TestEvent02 = public.CreateReq{
|
||||||
|
Title: "Test event 02",
|
||||||
|
Date: Time2pbtimestamp(time.Now().Add(60 * time.Second)),
|
||||||
|
Latency: Dur2pbduration(2 * 24 * time.Hour),
|
||||||
|
Note: "Note of test event 02",
|
||||||
|
NotifyTime: Dur2pbduration(5 * time.Minute),
|
||||||
|
UserID: 2222,
|
||||||
|
}
|
||||||
|
|
||||||
|
func Time2pbtimestamp(t time.Time) *timestamp.Timestamp {
|
||||||
|
r, err := ptypes.TimestampProto(t)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("cant convert Time to Timestamp: %s", err.Error())
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func Dur2pbduration(t time.Duration) *duration.Duration {
|
||||||
|
return ptypes.DurationProto(t)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user