mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-05 03:01:11 +00:00
Merge pull request #728 from weaveworks/make-make-build-ui
Make make build ui
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -34,8 +34,8 @@ coverage.html
|
||||
.*.uptodate
|
||||
scope.tar
|
||||
scope_ui_build.tar
|
||||
app/app
|
||||
app/scope-app
|
||||
prog/app/app
|
||||
prog/app/scope-app
|
||||
prog/probe/probe
|
||||
prog/probe/scope-probe
|
||||
docker/scope-app
|
||||
@@ -54,3 +54,5 @@ experimental/_integration/_integration
|
||||
*sublime-project
|
||||
*sublime-workspace
|
||||
*npm-debug.log
|
||||
app/static.go
|
||||
prog/app/static.go
|
||||
|
||||
23
Makefile
23
Makefile
@@ -3,7 +3,7 @@
|
||||
# If you can use Docker without being root, you can `make SUDO= <target>`
|
||||
SUDO=sudo -E
|
||||
DOCKERHUB_USER=weaveworks
|
||||
APP_EXE=app/scope-app
|
||||
APP_EXE=prog/app/scope-app
|
||||
PROBE_EXE=prog/probe/scope-probe
|
||||
FIXPROBE_EXE=experimental/fixprobe/fixprobe
|
||||
SCOPE_IMAGE=$(DOCKERHUB_USER)/scope
|
||||
@@ -38,7 +38,7 @@ $(SCOPE_EXPORT): $(APP_EXE) $(PROBE_EXE) $(DOCKER_DISTRIB) docker/weave $(RUNSVI
|
||||
|
||||
$(RUNSVINIT): vendor/runsvinit/*.go
|
||||
|
||||
$(APP_EXE): app/*.go render/*.go report/*.go xfer/*.go common/sanitize/*.go
|
||||
$(APP_EXE): app/*.go render/*.go report/*.go xfer/*.go common/sanitize/*.go prog/app/*.go prog/app/static.go
|
||||
|
||||
$(PROBE_EXE): prog/probe/*.go $(shell find probe/ -type f -name *.go) report/*.go xfer/*.go common/sanitize/*.go common/exec/*.go
|
||||
|
||||
@@ -62,30 +62,35 @@ $(RUNSVINIT):
|
||||
go build -ldflags "-extldflags \"-static\"" -o $@ ./$(@D)
|
||||
endif
|
||||
|
||||
static: client/build/app.js
|
||||
esc -o app/static.go -prefix client/build client/build
|
||||
static: prog/app/static.go
|
||||
|
||||
prog/app/static.go: client/build/app.js
|
||||
esc -o $@ -prefix client/build client/build
|
||||
|
||||
ifeq ($(BUILD_IN_CONTAINER),true)
|
||||
client/build/app.js: $(shell find client/app/scripts -type f)
|
||||
client/build/app.js: $(shell find client/app/scripts -type f) $(SCOPE_UI_BUILD_UPTODATE)
|
||||
mkdir -p client/build
|
||||
$(SUDO) docker run $(RM) $(RUN_FLAGS) -v $(shell pwd)/client/app:/home/weave/app \
|
||||
-v $(shell pwd)/client/build:/home/weave/build \
|
||||
$(SCOPE_UI_BUILD_IMAGE) npm run build
|
||||
|
||||
client-test: $(shell find client/app/scripts -type f)
|
||||
client-test: $(shell find client/app/scripts -type f) $(SCOPE_UI_BUILD_UPTODATE)
|
||||
$(SUDO) docker run $(RM) $(RUN_FLAGS) -v $(shell pwd)/client/app:/home/weave/app \
|
||||
-v $(shell pwd)/client/test:/home/weave/test \
|
||||
$(SCOPE_UI_BUILD_IMAGE) npm test
|
||||
|
||||
client-lint:
|
||||
client-lint: $(SCOPE_UI_BUILD_UPTODATE)
|
||||
$(SUDO) docker run $(RM) $(RUN_FLAGS) -v $(shell pwd)/client/app:/home/weave/app \
|
||||
-v $(shell pwd)/client/test:/home/weave/test \
|
||||
$(SCOPE_UI_BUILD_IMAGE) npm run lint
|
||||
|
||||
client-start:
|
||||
client-start: $(SCOPE_UI_BUILD_UPTODATE)
|
||||
$(SUDO) docker run $(RM) $(RUN_FLAGS) --net=host -v $(shell pwd)/client/app:/home/weave/app \
|
||||
-v $(shell pwd)/client/build:/home/weave/build \
|
||||
$(SCOPE_UI_BUILD_IMAGE) npm start
|
||||
else
|
||||
client/build/app.js:
|
||||
cd client && npm run build
|
||||
endif
|
||||
|
||||
$(SCOPE_UI_BUILD_UPTODATE): client/Dockerfile client/package.json client/webpack.local.config.js client/webpack.production.config.js client/server.js client/.eslintrc
|
||||
@@ -96,8 +101,6 @@ $(SCOPE_BACKEND_BUILD_UPTODATE): backend/*
|
||||
$(SUDO) docker build -t $(SCOPE_BACKEND_BUILD_IMAGE) backend
|
||||
touch $@
|
||||
|
||||
frontend: $(SCOPE_UI_BUILD_UPTODATE)
|
||||
|
||||
clean:
|
||||
go clean ./...
|
||||
$(SUDO) docker rmi $(SCOPE_UI_BUILD_IMAGE) $(SCOPE_BACKEND_BUILD_IMAGE) >/dev/null 2>&1 || true
|
||||
|
||||
12
README.md
12
README.md
@@ -192,16 +192,14 @@ Kubernetes-specific views "Pods", and "Pods by Service".
|
||||
|
||||
## <a name="developing"></a>Developing
|
||||
|
||||
The build is in five stages. `make deps` installs some tools we use later in
|
||||
the build. `make frontend` builds a UI build image with all NPM dependencies.
|
||||
`make static` compiles the UI into `static.go` which is part of the repository
|
||||
for convenience. The final `make` builds the app and probe, in a container,
|
||||
and pushes the lot into a Docker image called **weaveworks/scope**.
|
||||
The build is in two stages. `make deps` installs some tools we use later in
|
||||
the build. `make` builds the UI build container, builds the UI in said
|
||||
container, builds the backend build container, builds the app and probe in a
|
||||
said container, and finally pushes the lot into a Docker image called
|
||||
**weaveworks/scope**.
|
||||
|
||||
```
|
||||
make deps
|
||||
make frontend
|
||||
make static
|
||||
make
|
||||
```
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/report"
|
||||
)
|
||||
|
||||
func topologyServer() *httptest.Server {
|
||||
router := mux.NewRouter()
|
||||
app.RegisterTopologyRoutes(StaticReport{}, router)
|
||||
return httptest.NewServer(router)
|
||||
}
|
||||
|
||||
func TestAPIReport(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
defer ts.Close()
|
||||
|
||||
is404(t, ts, "/api/report/foobar")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -6,21 +6,24 @@ import (
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/probe/kubernetes"
|
||||
"github.com/weaveworks/scope/report"
|
||||
"github.com/weaveworks/scope/test/fixture"
|
||||
)
|
||||
|
||||
func TestAPITopology(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
defer ts.Close()
|
||||
|
||||
body := getRawJSON(t, ts, "/api/topology")
|
||||
|
||||
var topologies []APITopologyDesc
|
||||
var topologies []app.APITopologyDesc
|
||||
if err := json.Unmarshal(body, &topologies); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
@@ -48,12 +51,16 @@ func TestAPITopology(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAPITopologyAddsKubernetes(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
router := mux.NewRouter()
|
||||
c := app.NewCollector(1 * time.Minute)
|
||||
app.RegisterTopologyRoutes(c, router)
|
||||
app.RegisterReportPostHandler(c, router)
|
||||
ts := httptest.NewServer(router)
|
||||
defer ts.Close()
|
||||
|
||||
body := getRawJSON(t, ts, "/api/topology")
|
||||
|
||||
var topologies []APITopologyDesc
|
||||
var topologies []app.APITopologyDesc
|
||||
if err := json.Unmarshal(body, &topologies); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/render"
|
||||
"github.com/weaveworks/scope/render/expected"
|
||||
"github.com/weaveworks/scope/report"
|
||||
@@ -18,25 +18,25 @@ import (
|
||||
)
|
||||
|
||||
func TestAll(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
defer ts.Close()
|
||||
|
||||
body := getRawJSON(t, ts, "/api/topology")
|
||||
var topologies []APITopologyDesc
|
||||
var topologies []app.APITopologyDesc
|
||||
if err := json.Unmarshal(body, &topologies); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
|
||||
getTopology := func(topologyURL string) {
|
||||
body := getRawJSON(t, ts, topologyURL)
|
||||
var topology APITopology
|
||||
var topology app.APITopology
|
||||
if err := json.Unmarshal(body, &topology); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
|
||||
for _, node := range topology.Nodes {
|
||||
body := getRawJSON(t, ts, fmt.Sprintf("%s/%s", topologyURL, url.QueryEscape(node.ID)))
|
||||
var node APINode
|
||||
var node app.APINode
|
||||
if err := json.Unmarshal(body, &node); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
@@ -53,10 +53,10 @@ func TestAll(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAPITopologyContainers(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
{
|
||||
body := getRawJSON(t, ts, "/api/topology/containers")
|
||||
var topo APITopology
|
||||
var topo app.APITopology
|
||||
if err := json.Unmarshal(body, &topo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -73,12 +73,12 @@ func TestAPITopologyContainers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAPITopologyApplications(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
defer ts.Close()
|
||||
is404(t, ts, "/api/topology/applications/foobar")
|
||||
{
|
||||
body := getRawJSON(t, ts, "/api/topology/applications/"+expected.ServerProcessID)
|
||||
var node APINode
|
||||
var node app.APINode
|
||||
if err := json.Unmarshal(body, &node); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func TestAPITopologyApplications(t *testing.T) {
|
||||
}
|
||||
{
|
||||
body := getRawJSON(t, ts, fmt.Sprintf("/api/topology/applications/%s/%s", expected.ClientProcess1ID, expected.ServerProcessID))
|
||||
var edge APIEdge
|
||||
var edge app.APIEdge
|
||||
if err := json.Unmarshal(body, &edge); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
@@ -104,12 +104,12 @@ func TestAPITopologyApplications(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAPITopologyHosts(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
defer ts.Close()
|
||||
is404(t, ts, "/api/topology/hosts/foobar")
|
||||
{
|
||||
body := getRawJSON(t, ts, "/api/topology/hosts")
|
||||
var topo APITopology
|
||||
var topo app.APITopology
|
||||
if err := json.Unmarshal(body, &topo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func TestAPITopologyHosts(t *testing.T) {
|
||||
}
|
||||
{
|
||||
body := getRawJSON(t, ts, "/api/topology/hosts/"+expected.ServerHostRenderedID)
|
||||
var node APINode
|
||||
var node app.APINode
|
||||
if err := json.Unmarshal(body, &node); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -132,7 +132,7 @@ func TestAPITopologyHosts(t *testing.T) {
|
||||
}
|
||||
{
|
||||
body := getRawJSON(t, ts, fmt.Sprintf("/api/topology/hosts/%s/%s", expected.ClientHostRenderedID, expected.ServerHostRenderedID))
|
||||
var edge APIEdge
|
||||
var edge app.APIEdge
|
||||
if err := json.Unmarshal(body, &edge); err != nil {
|
||||
t.Fatalf("JSON parse error: %s", err)
|
||||
}
|
||||
@@ -146,7 +146,7 @@ func TestAPITopologyHosts(t *testing.T) {
|
||||
|
||||
// Basic websocket test
|
||||
func TestAPITopologyWebsocket(t *testing.T) {
|
||||
ts := httptest.NewServer(Router(StaticReport{}))
|
||||
ts := topologyServer()
|
||||
defer ts.Close()
|
||||
url := "/api/topology/applications/ws"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"sync"
|
||||
@@ -21,9 +21,15 @@ type Adder interface {
|
||||
Add(report.Report)
|
||||
}
|
||||
|
||||
// A Collector is a Reporter and an Adder
|
||||
type Collector interface {
|
||||
Reporter
|
||||
Adder
|
||||
}
|
||||
|
||||
// Collector receives published reports from multiple producers. It yields a
|
||||
// single merged report, representing all collected reports.
|
||||
type Collector struct {
|
||||
type collector struct {
|
||||
mtx sync.Mutex
|
||||
reports []timestampReport
|
||||
window time.Duration
|
||||
@@ -60,8 +66,8 @@ func (wc *waitableCondition) Broadcast() {
|
||||
}
|
||||
|
||||
// NewCollector returns a collector ready for use.
|
||||
func NewCollector(window time.Duration) *Collector {
|
||||
return &Collector{
|
||||
func NewCollector(window time.Duration) Collector {
|
||||
return &collector{
|
||||
window: window,
|
||||
waitableCondition: waitableCondition{
|
||||
waiters: map[chan struct{}]struct{}{},
|
||||
@@ -72,7 +78,7 @@ func NewCollector(window time.Duration) *Collector {
|
||||
var now = time.Now
|
||||
|
||||
// Add adds a report to the collector's internal state. It implements Adder.
|
||||
func (c *Collector) Add(rpt report.Report) {
|
||||
func (c *collector) Add(rpt report.Report) {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
c.reports = append(c.reports, timestampReport{now(), rpt})
|
||||
@@ -84,7 +90,7 @@ func (c *Collector) Add(rpt report.Report) {
|
||||
|
||||
// Report returns a merged report over all added reports. It implements
|
||||
// Reporter.
|
||||
func (c *Collector) Report() report.Report {
|
||||
func (c *collector) Report() report.Report {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/report"
|
||||
"github.com/weaveworks/scope/test"
|
||||
)
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
window := time.Millisecond
|
||||
c := NewCollector(window)
|
||||
c := app.NewCollector(window)
|
||||
|
||||
r1 := report.MakeReport()
|
||||
r1.Endpoint.AddNode("foo", report.MakeNode())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"log"
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
)
|
||||
|
||||
func registerControlRoutes(router *mux.Router) {
|
||||
// RegisterControlRoutes registers the various control routes with a http mux.
|
||||
func RegisterControlRoutes(router *mux.Router) {
|
||||
controlRouter := &controlRouter{
|
||||
probes: map[string]controlHandler{},
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -9,14 +9,15 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
)
|
||||
|
||||
func TestControl(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
registerControlRoutes(router)
|
||||
app.RegisterControlRoutes(router)
|
||||
server := httptest.NewServer(router)
|
||||
defer server.Close()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"github.com/weaveworks/scope/report"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
@@ -16,6 +16,14 @@ import (
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
)
|
||||
|
||||
var (
|
||||
// Version - set at buildtime.
|
||||
Version = "dev"
|
||||
|
||||
// UniqueID - set at runtime.
|
||||
UniqueID = "0"
|
||||
)
|
||||
|
||||
// URLMatcher uses request.RequestURI (the raw, unparsed request) to attempt
|
||||
// to match pattern. It does this as go's URL.Parse method is broken, and
|
||||
// mistakenly unescapes the Path before parsing it. This breaks %2F (encoded
|
||||
@@ -47,16 +55,12 @@ func URLMatcher(pattern string) mux.MatcherFunc {
|
||||
}
|
||||
}
|
||||
|
||||
type collector interface {
|
||||
Reporter
|
||||
Adder
|
||||
}
|
||||
|
||||
func gzipHandler(h http.HandlerFunc) http.HandlerFunc {
|
||||
return handlers.GZIPHandlerFunc(h, nil)
|
||||
}
|
||||
|
||||
func registerTopologyRoutes(c collector, router *mux.Router) {
|
||||
// RegisterTopologyRoutes registers the various topology routes with a http mux.
|
||||
func RegisterTopologyRoutes(c Reporter, router *mux.Router) {
|
||||
get := router.Methods("GET").Subrouter()
|
||||
get.HandleFunc("/api", gzipHandler(apiHandler))
|
||||
get.HandleFunc("/api/topology", gzipHandler(topologyRegistry.makeTopologyList(c)))
|
||||
@@ -69,13 +73,12 @@ func registerTopologyRoutes(c collector, router *mux.Router) {
|
||||
get.MatcherFunc(URLMatcher("/api/topology/{topology}/{local}/{remote}")).HandlerFunc(
|
||||
gzipHandler(topologyRegistry.captureRenderer(c, handleEdge)))
|
||||
get.HandleFunc("/api/report", gzipHandler(makeRawReportHandler(c)))
|
||||
|
||||
post := router.Methods("POST").Subrouter()
|
||||
post.HandleFunc("/api/report", makeReportPostHandler(c)).Methods("POST")
|
||||
}
|
||||
|
||||
func makeReportPostHandler(a Adder) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// RegisterReportPostHandler registers the handler for report submission
|
||||
func RegisterReportPostHandler(a Adder, router *mux.Router) {
|
||||
post := router.Methods("POST").Subrouter()
|
||||
post.HandleFunc("/api/report", func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
rpt report.Report
|
||||
reader = r.Body
|
||||
@@ -102,13 +105,13 @@ func makeReportPostHandler(a Adder) http.HandlerFunc {
|
||||
topologyRegistry.enableKubernetesTopologies()
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func apiHandler(w http.ResponseWriter, r *http.Request) {
|
||||
respondWith(w, http.StatusOK, xfer.Details{
|
||||
ID: uniqueID,
|
||||
Version: version,
|
||||
ID: UniqueID,
|
||||
Version: Version,
|
||||
Hostname: hostname.Get(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/test"
|
||||
"github.com/weaveworks/scope/test/fixture"
|
||||
)
|
||||
@@ -21,7 +23,7 @@ type v map[string]string
|
||||
func TestURLMatcher(t *testing.T) {
|
||||
test := func(pattern, path string, match bool, vars v) {
|
||||
routeMatch := &mux.RouteMatch{}
|
||||
if URLMatcher(pattern)(&http.Request{RequestURI: path}, routeMatch) != match {
|
||||
if app.URLMatcher(pattern)(&http.Request{RequestURI: path}, routeMatch) != match {
|
||||
t.Fatalf("'%s' '%s'", pattern, path)
|
||||
}
|
||||
if match && !reflect.DeepEqual(v(routeMatch.Vars), vars) {
|
||||
@@ -39,21 +41,38 @@ func TestURLMatcher(t *testing.T) {
|
||||
|
||||
func TestReportPostHandler(t *testing.T) {
|
||||
test := func(contentType string, encoder func(interface{}) ([]byte, error)) {
|
||||
router := mux.NewRouter()
|
||||
c := app.NewCollector(1 * time.Minute)
|
||||
app.RegisterReportPostHandler(c, router)
|
||||
ts := httptest.NewServer(router)
|
||||
defer ts.Close()
|
||||
|
||||
b, err := encoder(fixture.Report)
|
||||
if err != nil {
|
||||
t.Fatalf("Content-Type %s: %s", contentType, err)
|
||||
}
|
||||
|
||||
r, _ := http.NewRequest("POST", "/api/report", bytes.NewReader(b))
|
||||
r.Header.Set("Content-Type", contentType)
|
||||
w := httptest.NewRecorder()
|
||||
c := NewCollector(1 * time.Minute)
|
||||
makeReportPostHandler(c).ServeHTTP(w, r)
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("Content-Type %s: http status: %d\nbody: %s", contentType, w.Code, w.Body.String())
|
||||
req, err := http.NewRequest("POST", ts.URL+"/api/report", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
t.Fatalf("Error posting report: %v", err)
|
||||
}
|
||||
// Just check a few items, to confirm it parsed. Otherwise
|
||||
// reflect.DeepEqual chokes on nil vs empty arrays.
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatalf("Error posting report %v", err)
|
||||
}
|
||||
|
||||
_, err = ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("Error posting report: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("Error posting report: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
if want, have := fixture.Report.Endpoint.Nodes, c.Report().Endpoint.Nodes; len(have) == 0 || len(want) != len(have) {
|
||||
t.Fatalf("Content-Type %s: %v", contentType, test.Diff(have, want))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// Basic site layout tests.
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Test site
|
||||
func TestSite(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
registerStatic(router)
|
||||
ts := httptest.NewServer(router)
|
||||
defer ts.Close()
|
||||
|
||||
is200(t, ts, "/")
|
||||
is200(t, ts, "/index.html")
|
||||
is404(t, ts, "/index.html/foobar")
|
||||
}
|
||||
18899
app/static.go
18899
app/static.go
File diff suppressed because it is too large
Load Diff
@@ -39,9 +39,9 @@ test:
|
||||
parallel: true
|
||||
- cd $SRCDIR; make RM= static:
|
||||
parallel: true
|
||||
- cd $SRCDIR; rm -f app/scope-app prog/probe/scope-probe; if [ "$CIRCLE_NODE_INDEX" = "0" ]; then GOARCH=arm make RM= app/scope-app prog/probe/scope-probe; else GOOS=darwin make RM= app/scope-app prog/probe/scope-probe; fi:
|
||||
- cd $SRCDIR; rm -f prog/app/scope-app prog/probe/scope-probe; if [ "$CIRCLE_NODE_INDEX" = "0" ]; then GOARCH=arm make RM= prog/app/scope-app prog/probe/scope-probe; else GOOS=darwin make RM= prog/app/scope-app prog/probe/scope-probe; fi:
|
||||
parallel: true
|
||||
- cd $SRCDIR; rm -f app/scope-app prog/probe/scope-probe; make RM=:
|
||||
- cd $SRCDIR; rm -f prog/app/scope-app prog/probe/scope-probe; make RM=:
|
||||
parallel: true
|
||||
- cd $SRCDIR/experimental; ./build_on_circle.sh:
|
||||
parallel: true
|
||||
|
||||
@@ -14,27 +14,17 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/weaveworks/weave/common"
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/xfer"
|
||||
)
|
||||
|
||||
var (
|
||||
// Set at buildtime.
|
||||
version = "dev"
|
||||
|
||||
// Set at runtime.
|
||||
uniqueID = "0"
|
||||
)
|
||||
|
||||
func registerStatic(router *mux.Router) {
|
||||
router.Methods("GET").PathPrefix("/").Handler(http.FileServer(FS(false)))
|
||||
}
|
||||
|
||||
// Router creates the mux for all the various app components.
|
||||
func Router(c collector) *mux.Router {
|
||||
func Router(c app.Collector) *mux.Router {
|
||||
router := mux.NewRouter()
|
||||
registerTopologyRoutes(c, router)
|
||||
registerControlRoutes(router)
|
||||
registerStatic(router)
|
||||
app.RegisterTopologyRoutes(c, router)
|
||||
app.RegisterReportPostHandler(c, router)
|
||||
app.RegisterControlRoutes(router)
|
||||
router.Methods("GET").PathPrefix("/").Handler(http.FileServer(FS(false)))
|
||||
return router
|
||||
}
|
||||
|
||||
@@ -48,7 +38,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *printVersion {
|
||||
fmt.Println(version)
|
||||
fmt.Println(app.Version)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -60,11 +50,9 @@ func main() {
|
||||
defer log.Print("app exiting")
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
uniqueID = strconv.FormatInt(rand.Int63(), 16)
|
||||
log.Printf("app starting, version %s, ID %s", version, uniqueID)
|
||||
|
||||
c := NewCollector(*window)
|
||||
http.Handle("/", Router(c))
|
||||
app.UniqueID = strconv.FormatInt(rand.Int63(), 16)
|
||||
log.Printf("app starting, version %s, ID %s", app.Version, app.UniqueID)
|
||||
http.Handle("/", Router(app.NewCollector(*window)))
|
||||
go func() {
|
||||
log.Printf("listening on %s", *listen)
|
||||
log.Print(http.ListenAndServe(*listen, nil))
|
||||
Reference in New Issue
Block a user