diff --git a/.circleci/config.yml b/.circleci/config.yml index 8d0c6679b375cc43f46b0b8906c58a738a83306e..c76f6f58f5f2c6efdb7721dc8c389e1a91ad7079 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,3 +17,25 @@ jobs: - store_artifacts: path: bin/import_synapse destination: import_synapse + sytest: + docker: + - image: asd + working_directory: /go/src/github.com/turt2live/matrix-media-repo + steps: + # Build the project + - checkout + - run: go get github.com/constabulary/gb/... + - run: gb vendor restore + - run: gb build all + # Install sytest + - run: cd /test + - run: wget -q https://github.com/matrix-org/sytest/archive/develop.tar.gz -O sytest.tar.gz + - run: tar --strip-components=1 -xf sytest.tar.gz + # Finally, run the tests + - run: ./run-tests.sh +workflows: + version: 2 + build_and_test: + jobs: + - build + - sytest diff --git a/Dockerfile-sytest b/Dockerfile-sytest new file mode 100644 index 0000000000000000000000000000000000000000..e809a3477c9a6e872f03f88c646af869797a3659 --- /dev/null +++ b/Dockerfile-sytest @@ -0,0 +1,20 @@ +FROM matrixdotorg/sytest:latest + +RUN apt-get -qq install -y curl nginx dos2unix \ + && curl -O https://dl.google.com/go/go1.10.2.linux-amd64.tar.gz \ + && tar xvf go1.10.2.linux-amd64.tar.gz \ + && chown -R root:root ./go \ + && mv go /usr/local \ + && mkdir /go \ + && openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \ + && openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + +COPY docker/sytest/site.conf /etc/nginx/sites-available/default +COPY docker/sytest/run-tests.sh /test/run-tests.sh +COPY docker/sytest/media-repo.yaml /test/media-repo.yaml +COPY docker/sytest/03ascii.patch /test/03ascii.patch + +RUN dos2unix /test/run-tests.sh + +ENV GOPATH=/go +ENV PATH="${PATH}:/usr/local/go/bin:/go/bin" \ No newline at end of file diff --git a/docker/sytest/03ascii.patch b/docker/sytest/03ascii.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ddfcb4d2e9066a1083bc806de1c14086a3ae5ab --- /dev/null +++ b/docker/sytest/03ascii.patch @@ -0,0 +1,52 @@ +--- tests/51media/03ascii.pl 2018-11-07 11:28:39.000000000 +0000 ++++ tests/51media/03ascii_mediaonly.pl 2018-11-11 03:50:11.642993500 +0000 +@@ -97,49 +97,3 @@ + }); + }; + +-test "Can send image in room message", +- requires => [ $main::API_CLIENTS[0], local_user_and_room_fixtures() ], +- +- check => sub { +- my ( $http, $user, $room_id ) = @_; +- test_using_client( $http ) +- ->then( sub { +- matrix_send_room_message( $user, $room_id, +- content => { msgtype => "m.file", body => "test.txt", url => $content_uri } +- ) +- }); +- }; +- +-test "Can fetch images in room", +- requires => [ $main::API_CLIENTS[0], local_user_and_room_fixtures() ], +- +- check => sub { +- my ( $http, $user, $room_id ) = @_; +- test_using_client( $http ) +- ->then( sub { +- matrix_send_room_message_synced( $user, $room_id, +- content => { msgtype => "m.text", body => "test" } +- ) +- })->then( sub { +- matrix_send_room_message_synced( $user, $room_id, +- content => { msgtype => "m.file", body => "test.txt", url => $content_uri } +- ) +- })->then( sub { +- do_request_json_for( $user, +- method => "GET", +- uri => "/api/v1/rooms/$room_id/messages", +- params => { +- filter => '{"contains_url":true}', +- dir => 'b', +- } +- ) +- })->then( sub { +- my ( $body ) = @_; +- +- assert_json_keys( $body, qw( start end chunk )); +- +- assert_eq( scalar @{ $body->{chunk} }, 1, "Expected 1 message" ); +- +- Future->done( 1 ); +- }); +- }; diff --git a/docker/sytest/run-tests.sh b/docker/sytest/run-tests.sh new file mode 100644 index 0000000000000000000000000000000000000000..b49e0353d0410c030341abd511b8bfa151e1c178 --- /dev/null +++ b/docker/sytest/run-tests.sh @@ -0,0 +1,20 @@ +#!/bin/bash +cd /test +/go/src/github.com/turt2live/matrix-media-repo/bin/media_repo -config /test/media-repo.yaml -migrations /go/src/github.com/turt2live/matrix-media-repo/migrations & pid_mr=$! +/go/src/github.com/turt2live/matrix-media-repo/bin/sytest_homeserver & pid_hs=$! +nginx + +mkdir -p /tmp/mr/uploads +mkdir -p /tmp/mr/logs + +export PGDATA=/var/lib/postgresql/data +su -c '/usr/lib/postgresql/9.6/bin/initdb -E "UTF-8" --lc-collate="en_US.UTF-8" --lc-ctype="en_US.UTF-8" --username=postgres' postgres +su -c '/usr/lib/postgresql/9.6/bin/pg_ctl -w -D /var/lib/postgresql/data start' postgres +su -c 'psql -c "CREATE DATABASE mediarepo;"' postgres + +patch tests/51media/03ascii.pl 03ascii.patch +./run-tests.pl -I Manual -L https://localhost --server-name example.org tests/51media/* + +kill -9 $pid_mr +kill -9 $pid_hs +nginx -s stop diff --git a/docker/sytest/site.conf b/docker/sytest/site.conf new file mode 100644 index 0000000000000000000000000000000000000000..061915cebb8b95914bb18255b11d79a94754b403 --- /dev/null +++ b/docker/sytest/site.conf @@ -0,0 +1,47 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + + return 302 https://localhost$request_uri; +} + +server { + listen 443 ssl default_server; + listen [::]:443 ssl default_server; + + ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; + ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + ssl_ecdh_curve secp384r1; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + resolver 8.8.8.8 8.8.4.4 valid=300s; + resolver_timeout 5s; + + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + + ssl_dhparam /etc/ssl/certs/dhparam.pem; + + location / { + proxy_read_timeout 600s; + proxy_set_header Host example.org; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_pass http://localhost:8000; + } + + location /_matrix/client { + proxy_read_timeout 600s; + proxy_set_header Host example.org; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_pass http://localhost:8001; + } +} \ No newline at end of file diff --git a/src/github.com/turt2live/matrix-media-repo/cmd/sytest_homeserver/main.go b/src/github.com/turt2live/matrix-media-repo/cmd/sytest_homeserver/main.go new file mode 100644 index 0000000000000000000000000000000000000000..de9cf30f6a2323327fbf0cc6f361e10aa4e895aa --- /dev/null +++ b/src/github.com/turt2live/matrix-media-repo/cmd/sytest_homeserver/main.go @@ -0,0 +1,89 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/gorilla/mux" + "github.com/turt2live/matrix-media-repo/util" +) + +// This is a limited in-memory homeserver used for the purposes of facilitating the tests + +type user struct { + localpart string + domain string + mxid string +} + +var accessTokenMap = make(map[string]user) + +func main() { + rtr := mux.NewRouter() + rtr.Handle("/_matrix/client/r0/register", register{}).Methods("POST") + rtr.Handle("/_matrix/client/r0/account/whoami", whoami{}).Methods("GET") + + http.Handle("/", rtr) + http.ListenAndServe("localhost:8001", nil) +} + +type registerResponse struct { + UserID string `json:"user_id"` + AccessToken string `json:"access_token"` + DeviceID string `json:"device_id"` +} +type registerRequest struct { + Username string `json:"username"` +} + +type register struct{} + +func (c register) ServeHTTP(w http.ResponseWriter, r *http.Request) { + decoder := json.NewDecoder(r.Body) + var t registerRequest + err := decoder.Decode(&t) + if err != nil { + panic(err) + } + + token, err := util.GenerateRandomString(32) + if err != nil { + panic(err) + } + + accessTokenMap[token] = user{ + localpart: t.Username, + domain: "example.org", + mxid: fmt.Sprintf("@%s:example.org", t.Username), + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + encoder := json.NewEncoder(w) + encoder.Encode(registerResponse{ + UserID: accessTokenMap[token].mxid, + AccessToken: token, + DeviceID: "example", + }) +} + +type whoamiResponse struct { + UserID string `json:"user_id"` +} + +type whoami struct{} + +func (c whoami) ServeHTTP(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("Authorization") + token = token[len("Bearer "):] + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + encoder := json.NewEncoder(w) + encoder.Encode(whoamiResponse{ + UserID: accessTokenMap[token].mxid, + }) +}