Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

weaveworks / weave / #6002

13 Apr 2016 - 6:49 coverage decreased (-0.1%) to 75.607%
#6002

Pull #2154

circleci

2f1e5f233f2b7283a9bf3277e75bf30a?size=18&default=identiconrade
Lock round TestRouter map accesses, and copy the set where we may block.
Pull Request #2154: Lock round TestRouter map accesses

6137 of 8117 relevant lines covered (75.61%)

129553.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.11
/prog/weaver/http.go
1
package main
2

3
import (
4
        "bytes"
5
        "encoding/json"
6
        "fmt"
7
        "net/http"
8
        "strings"
9
        "text/template"
10

11
        "github.com/gorilla/mux"
12
        "github.com/weaveworks/mesh"
13

14
        "github.com/weaveworks/weave/ipam"
15
        "github.com/weaveworks/weave/nameserver"
16
        "github.com/weaveworks/weave/net/address"
17
        weave "github.com/weaveworks/weave/router"
18
)
19

20
var rootTemplate = template.New("root").Funcs(map[string]interface{}{
21
        "countDNSEntries": func(entries []nameserver.EntryStatus) int {
139×
22
                count := 0
139×
23
                for _, entry := range entries {
171×
24
                        if entry.Tombstone == 0 {
42×
25
                                count++
10×
26
                        }
10×
27
                }
28
                return count
139×
29
        },
30
        "printList": func(list []string) string {
280×
31
                if len(list) == 0 {
417×
32
                        return "none"
137×
33
                }
137×
34
                return strings.Join(list, ", ")
143×
35
        },
36
        "printIPAMRanges": func(router weave.NetworkRouterStatus, status ipam.Status) string {
3×
37
                var buffer bytes.Buffer
3×
38

3×
39
                type stats struct {
3×
40
                        ips       uint32
3×
41
                        nickname  string
3×
42
                        reachable bool
3×
43
                }
3×
44

3×
45
                peerStats := make(map[string]*stats)
3×
46

3×
47
                for _, entry := range status.Entries {
3×
48
                        s, found := peerStats[entry.Peer]
!
49
                        if !found {
!
50
                                s = &stats{nickname: entry.Nickname, reachable: entry.IsKnownPeer}
!
51
                                peerStats[entry.Peer] = s
!
52
                        }
!
53
                        s.ips += entry.Size
!
54
                }
55

56
                printOwned := func(name string, nickName string, reachable bool, ips uint32) {
3×
57
                        reachableStr := ""
!
58
                        if !reachable {
!
59
                                reachableStr = "- unreachable!"
!
60
                        }
!
61
                        percentageRanges := float32(ips) * 100.0 / float32(status.RangeNumIPs)
!
62

!
63
                        displayName := name + "(" + nickName + ")"
!
64
                        fmt.Fprintf(&buffer, "%-37v %8d IPs (%04.1f%% of total) %s\n",
!
65
                                displayName, ips, percentageRanges, reachableStr)
!
66
                }
67

68
                // print the local info first
69
                if ourStats := peerStats[router.Name]; ourStats != nil {
3×
70
                        printOwned(router.Name, ourStats.nickname, true, ourStats.ips)
!
71
                }
!
72

73
                // and then the rest
74
                for peer, stats := range peerStats {
3×
75
                        if peer != router.Name {
!
76
                                printOwned(peer, stats.nickname, stats.reachable, stats.ips)
!
77
                        }
!
78
                }
79

80
                return buffer.String()
3×
81
        },
82
        "allIPAMOwnersUnreachable": func(status ipam.Status) bool {
16×
83
                for _, entry := range status.Entries {
35×
84
                        if entry.Size > 0 && entry.IsKnownPeer {
35×
85
                                return false
16×
86
                        }
16×
87
                }
88
                return true
!
89
        },
90
        "printConnectionCounts": func(conns []mesh.LocalConnectionStatus) string {
141×
91
                counts := make(map[string]int)
141×
92
                for _, conn := range conns {
203×
93
                        counts[conn.State]++
62×
94
                }
62×
95
                return printCounts(counts, []string{"established", "pending", "retrying", "failed", "connecting"})
141×
96
        },
97
        "printPeerConnectionCounts": func(peers []mesh.PeerStatus) string {
141×
98
                counts := make(map[string]int)
141×
99
                for _, peer := range peers {
333×
100
                        for _, conn := range peer.Connections {
313×
101
                                if conn.Established {
242×
102
                                        counts["established"]++
121×
103
                                } else {
121×
UNCOV
104
                                        counts["pending"]++
!
UNCOV
105
                                }
!
106
                        }
107
                }
108
                return printCounts(counts, []string{"established", "pending"})
141×
109
        },
110
        "printState": func(enabled bool) string {
282×
111
                if enabled {
422×
112
                        return "enabled"
140×
113
                }
140×
114
                return "disabled"
142×
115
        },
116
        "trimSuffix": strings.TrimSuffix,
117
})
118

119
// Print counts in a specified order
120
func printCounts(counts map[string]int, keys []string) string {
282×
121
        var stringCounts []string
282×
122
        for _, key := range keys {
1,269×
123
                if count, ok := counts[key]; ok {
1,073×
124
                        stringCounts = append(stringCounts, fmt.Sprintf("%d %s", count, key))
86×
125
                }
86×
126
        }
127
        return strings.Join(stringCounts, ", ")
282×
128
}
129

130
// Strip escaped newlines from template
131
func escape(template string) string {
468×
132
        return strings.Replace(template, "\\\n", "", -1)
468×
133
}
468×
134

135
// Define a named template panicking on error
136
func defTemplate(name string, text string) *template.Template {
468×
137
        return template.Must(rootTemplate.New(name).Parse(escape(text)))
468×
138
}
468×
139

140
var statusTemplate = defTemplate("status", `\
141
        Version: {{.Version}}
142

143
        Service: router
144
       Protocol: {{.Router.Protocol}} \
145
{{if eq .Router.ProtocolMinVersion .Router.ProtocolMaxVersion}}\
146
{{.Router.ProtocolMaxVersion}}\
147
{{else}}\
148
{{.Router.ProtocolMinVersion}}..{{.Router.ProtocolMaxVersion}}\
149
{{end}}
150
           Name: {{.Router.Name}}({{.Router.NickName}})
151
     Encryption: {{printState .Router.Encryption}}
152
  PeerDiscovery: {{printState .Router.PeerDiscovery}}
153
        Targets: {{len .Router.Targets}}
154
    Connections: {{len .Router.Connections}}{{with printConnectionCounts .Router.Connections}} ({{.}}){{end}}
155
          Peers: {{len .Router.Peers}}{{with printPeerConnectionCounts .Router.Peers}} (with {{.}} connections){{end}}
156
 TrustedSubnets: {{printList .Router.TrustedSubnets}}
157
{{if .IPAM}}\
158

159
        Service: ipam
160
{{if .IPAM.Entries}}\
161
{{if allIPAMOwnersUnreachable .IPAM}}\
162
         Status: all IP ranges owned by unreachable peers - use 'rmpeer' if they are dead
163
{{else if len .IPAM.PendingAllocates}}\
164
         Status: waiting for IP range grant from peers
165
{{else}}\
166
         Status: ready
167
{{end}}\
168
{{else if .IPAM.Paxos}}\
169
{{if .IPAM.Paxos.Elector}}\
170
         Status: awaiting consensus (quorum: {{.IPAM.Paxos.Quorum}}, known: {{.IPAM.Paxos.KnownNodes}})
171
{{else}}\
172
         Status: awaiting consensus (observer)
173
{{end}}\
174
{{else}}\
175
         Status: idle
176
{{end}}\
177
          Range: {{.IPAM.Range}}
178
  DefaultSubnet: {{.IPAM.DefaultSubnet}}
179
{{end}}\
180
{{if .DNS}}\
181

182
        Service: dns
183
         Domain: {{.DNS.Domain}}
184
       Upstream: {{printList .DNS.Upstream}}
185
            TTL: {{.DNS.TTL}}
186
        Entries: {{countDNSEntries .DNS.Entries}}
187
{{end}}\
188
`)
189

190
var targetsTemplate = defTemplate("targetsTemplate", `\
191
{{range .Router.Targets}}{{.}}
192
{{end}}\
193
`)
194

195
var connectionsTemplate = defTemplate("connectionsTemplate", `\
196
{{range .Router.Connections}}\
197
{{if .Outbound}}->{{else}}<-{{end}} {{printf "%-21v" .Address}} {{printf "%-11v" .State}} {{.Info}}
198
{{end}}\
199
`)
200

201
var peersTemplate = defTemplate("peers", `\
202
{{range .Router.Peers}}\
203
{{.Name}}({{.NickName}})
204
{{range .Connections}}\
205
   {{if .Outbound}}->{{else}}<-{{end}} {{printf "%-21v" .Address}} \
206
{{$nameNickName := printf "%v(%v)" .Name .NickName}}{{printf "%-37v" $nameNickName}} \
207
{{if .Established}}established{{else}}pending{{end}}
208
{{end}}\
209
{{end}}\
210
`)
211

212
var dnsEntriesTemplate = defTemplate("dnsEntries", `\
213
{{$domain := printf ".%v" .DNS.Domain}}\
214
{{range .DNS.Entries}}\
215
{{if eq .Tombstone 0}}\
216
{{$hostname := trimSuffix .Hostname $domain}}\
217
{{printf "%-12v" $hostname}} {{printf "%-15v" .Address}} {{printf "%12.12v" .ContainerID}} {{.Origin}}
218
{{end}}\
219
{{end}}\
220
`)
221

222
var ipamTemplate = defTemplate("ipamTemplate", `{{printIPAMRanges .Router .IPAM}}`)
223

224
type WeaveStatus struct {
225
        Version string
226
        Router  *weave.NetworkRouterStatus `json:"Router,omitempty"`
227
        IPAM    *ipam.Status               `json:"IPAM,omitempty"`
228
        DNS     *nameserver.Status         `json:"DNS,omitempty"`
229
}
230

231
func HandleHTTP(muxRouter *mux.Router, version string, router *weave.NetworkRouter, allocator *ipam.Allocator, defaultSubnet address.CIDR, ns *nameserver.Nameserver, dnsserver *nameserver.DNSServer) {
78×
232
        status := func() WeaveStatus {
237×
233
                return WeaveStatus{
159×
234
                        version,
159×
235
                        weave.NewNetworkRouterStatus(router),
159×
236
                        ipam.NewStatus(allocator, defaultSubnet),
159×
237
                        nameserver.NewStatus(ns, dnsserver)}
159×
238
        }
159×
239
        muxRouter.Methods("GET").Path("/report").Headers("Accept", "application/json").HandlerFunc(
78×
240
                func(w http.ResponseWriter, r *http.Request) {
79×
241
                        json, err := json.MarshalIndent(status(), "", "    ")
1×
242
                        if err != nil {
1×
243
                                http.Error(w, err.Error(), http.StatusInternalServerError)
!
244
                                Log.Error("Error during report marshalling: ", err)
!
245
                                return
!
246
                        }
!
247
                        w.Header().Set("Content-Type", "application/json")
1×
248
                        w.Write(json)
1×
249
                })
250

251
        muxRouter.Methods("GET").Path("/report").Queries("format", "{format}").HandlerFunc(
78×
252
                func(w http.ResponseWriter, r *http.Request) {
85×
253
                        funcs := template.FuncMap{
7×
254
                                "json": func(v interface{}) string {
7×
255
                                        a, _ := json.Marshal(v)
!
256
                                        return string(a)
!
257
                                },
!
258
                        }
259
                        formatTemplate, err := template.New("format").Funcs(funcs).Parse(mux.Vars(r)["format"])
7×
260
                        if err != nil {
7×
261
                                http.Error(w, err.Error(), http.StatusBadRequest)
!
262
                                return
!
263
                        }
!
264
                        if err := formatTemplate.Execute(w, status()); err != nil {
7×
265
                                http.Error(w, "error during template execution", http.StatusInternalServerError)
!
266
                                Log.Error(err)
!
267
                        }
!
268
                })
269

270
        defHandler := func(path string, template *template.Template) {
546×
271
                muxRouter.Methods("GET").Path(path).HandlerFunc(
468×
272
                        func(w http.ResponseWriter, r *http.Request) {
619×
273
                                if err := template.Execute(w, status()); err != nil {
151×
274
                                        http.Error(w, "error during template execution", http.StatusInternalServerError)
!
275
                                        Log.Error(err)
!
276
                                }
!
277
                        })
278
        }
279

280
        defHandler("/status", statusTemplate)
78×
281
        defHandler("/status/targets", targetsTemplate)
78×
282
        defHandler("/status/connections", connectionsTemplate)
78×
283
        defHandler("/status/peers", peersTemplate)
78×
284
        defHandler("/status/dns", dnsEntriesTemplate)
78×
285
        defHandler("/status/ipam", ipamTemplate)
78×
286

287
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2022 Coveralls, Inc