Merge lp:~pedronis/ubuntu-push/kindpool-test-derace into lp:ubuntu-push

Proposed by Samuele Pedroni
Status: Superseded
Proposed branch: lp:~pedronis/ubuntu-push/kindpool-test-derace
Merge into: lp:ubuntu-push
Diff against target: 1106 lines (+405/-177)
18 files modified
bus/notifications/raw.go (+1/-1)
bus/notifications/raw_test.go (+13/-0)
click/click.go (+13/-0)
click/click_test.go (+18/-0)
client/client_test.go (+6/-2)
dependencies.tsv (+1/-1)
launch_helper/kindpool.go (+1/-1)
launch_helper/kindpool_test.go (+10/-3)
launch_helper/legacy/legacy.go (+20/-6)
launch_helper/legacy/legacy_test.go (+16/-2)
server/acceptance/acceptanceclient.go (+15/-16)
server/acceptance/cmd/acceptanceclient.go (+54/-0)
server/acceptance/kit/api.go (+82/-0)
server/acceptance/kit/cliloop.go (+75/-52)
server/acceptance/kit/helpers.go (+46/-0)
server/acceptance/suites/broadcast.go (+14/-27)
server/acceptance/suites/suite.go (+5/-40)
server/acceptance/suites/unicast.go (+15/-26)
To merge this branch: bzr merge lp:~pedronis/ubuntu-push/kindpool-test-derace
Reviewer Review Type Date Requested Status
Ubuntu Push Hackers Pending
Review via email: mp+231905@code.launchpad.net

Commit message

avoid rare race in kindpool_test.go

Description of the change

avoid rare race in test,

better to change globals once in SetUpSuite than again and again in SetUpTest

To post a comment you must log in.
314. By Samuele Pedroni

avoid rare race in test

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bus/notifications/raw.go'
--- bus/notifications/raw.go 2014-07-27 00:58:08 +0000
+++ bus/notifications/raw.go 2014-08-22 14:47:03 +0000
@@ -144,7 +144,7 @@
144 }144 }
145145
146 hints := make(map[string]*dbus.Variant)146 hints := make(map[string]*dbus.Variant)
147 hints["x-canonical-secondary-icon"] = &dbus.Variant{app.Icon()}147 hints["x-canonical-secondary-icon"] = &dbus.Variant{app.SymbolicIcon()}
148148
149 appId := app.Original()149 appId := app.Original()
150 actions := make([]string, 2*len(card.Actions))150 actions := make([]string, 2*len(card.Actions))
151151
=== modified file 'bus/notifications/raw_test.go'
--- bus/notifications/raw_test.go 2014-07-27 00:58:08 +0000
+++ bus/notifications/raw_test.go 2014-08-22 14:47:03 +0000
@@ -210,6 +210,19 @@
210 c.Check(hints["x-canonical-secondary-icon"], NotNil)210 c.Check(hints["x-canonical-secondary-icon"], NotNil)
211}211}
212212
213func (s *RawSuite) TestPresentUsesSymbolic(c *C) {
214 endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
215 raw := Raw(endp, s.log)
216 worked := raw.Present(s.app, "notifId", &launch_helper.Notification{Card: &launch_helper.Card{Summary: "summary", Popup: true}})
217 c.Assert(worked, Equals, true)
218 callArgs := testibus.GetCallArgs(endp)
219 c.Assert(callArgs, HasLen, 1)
220 c.Assert(callArgs[0].Args, HasLen, 8)
221 hints, ok := callArgs[0].Args[6].(map[string]*dbus.Variant)
222 c.Assert(ok, Equals, true)
223 c.Check(hints["x-canonical-secondary-icon"].Value.(string), Equals, "-symbolic")
224}
225
213func (s *RawSuite) TestPresentNoNotificationPanics(c *C) {226func (s *RawSuite) TestPresentNoNotificationPanics(c *C) {
214 endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))227 endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
215 raw := Raw(endp, s.log)228 raw := Raw(endp, s.log)
216229
=== modified file 'click/click.go'
--- click/click.go 2014-08-06 02:44:06 +0000
+++ click/click.go 2014-08-22 14:47:03 +0000
@@ -136,6 +136,19 @@
136 return cappinfo.AppIconFromDesktopId(app.DesktopId())136 return cappinfo.AppIconFromDesktopId(app.DesktopId())
137}137}
138138
139func _symbolic(icon string) string {
140 if strings.ContainsRune(icon, '/') {
141 return icon
142 }
143 return icon + "-symbolic"
144}
145
146var symbolic = _symbolic
147
148func (app *AppId) SymbolicIcon() string {
149 return symbolic(app.Icon())
150}
151
139func (app *AppId) MarshalJSON() ([]byte, error) {152func (app *AppId) MarshalJSON() ([]byte, error) {
140 return json.Marshal(app.Original())153 return json.Marshal(app.Original())
141}154}
142155
=== modified file 'click/click_test.go'
--- click/click_test.go 2014-08-06 03:50:14 +0000
+++ click/click_test.go 2014-08-22 14:47:03 +0000
@@ -182,3 +182,21 @@
182 c.Check(app, NotNil)182 c.Check(app, NotNil)
183 c.Check(app.Original(), Equals, "_non-existent-app")183 c.Check(app.Original(), Equals, "_non-existent-app")
184}184}
185
186func (s *clickSuite) TestSymbolicAppendsSymbolicIfIconIsName(c *C) {
187 symb := symbolic("foo")
188 c.Check(symb, Equals, "foo-symbolic")
189}
190
191func (s *clickSuite) TestSymbolicLeavesAloneIfIconIsPath(c *C) {
192 symb := symbolic("foo/bar")
193 c.Check(symb, Equals, "foo/bar")
194}
195
196func (s *clickSuite) TestSymbolicIconCallsSymbolic(c *C) {
197 symbolic = func(string) string { return "xyzzy" }
198 defer func() { symbolic = _symbolic }()
199 app, err := ParseAppId("_python3.4")
200 c.Assert(err, IsNil)
201 c.Check(app.SymbolicIcon(), Equals, "xyzzy")
202}
185203
=== modified file 'client/client_test.go'
--- client/client_test.go 2014-08-12 00:32:32 +0000
+++ client/client_test.go 2014-08-22 14:47:03 +0000
@@ -143,7 +143,11 @@
143143
144func (cs *clientSuite) SetUpSuite(c *C) {144func (cs *clientSuite) SetUpSuite(c *C) {
145 config.IgnoreParsedFlags = true // because configure() uses <flags>145 config.IgnoreParsedFlags = true // because configure() uses <flags>
146 newIdentifier = func() (identifier.Id, error) { return idtesting.Settable(), nil }146 newIdentifier = func() (identifier.Id, error) {
147 id := idtesting.Settable()
148 id.Set("42") // must be hex of len 32
149 return id, nil
150 }
147 cs.timeouts = util.SwapTimeouts([]time.Duration{0})151 cs.timeouts = util.SwapTimeouts([]time.Duration{0})
148 cs.leveldbPath = ""152 cs.leveldbPath = ""
149}153}
@@ -1141,7 +1145,7 @@
1141 // and now everthing is better! We have a config,1145 // and now everthing is better! We have a config,
1142 c.Check(string(cli.config.Addr), Equals, ":0")1146 c.Check(string(cli.config.Addr), Equals, ":0")
1143 // and a device id,1147 // and a device id,
1144 c.Check(cli.deviceId, HasLen, 32)1148 c.Check(cli.deviceId, HasLen, 40)
1145 // and a session,1149 // and a session,
1146 c.Check(cli.session, NotNil)1150 c.Check(cli.session, NotNil)
1147 // and a bus,1151 // and a bus,
11481152
=== modified file 'dependencies.tsv'
--- dependencies.tsv 2014-07-26 07:28:59 +0000
+++ dependencies.tsv 2014-08-22 14:47:03 +0000
@@ -1,5 +1,5 @@
1code.google.com/p/go-uuid hg 7dda39b2e7d5e265014674c5af696ba4186679e9 111code.google.com/p/go-uuid hg 7dda39b2e7d5e265014674c5af696ba4186679e9 11
2code.google.com/p/gosqlite hg 74691fb6f83716190870cde1b658538dd4b18eb0 152code.google.com/p/gosqlite hg 74691fb6f83716190870cde1b658538dd4b18eb0 15
3launchpad.net/go-dbus/v1 bzr james@jamesh.id.au-20140530132806-hpqbkxczif6o1dpz 1273launchpad.net/go-dbus/v1 bzr james@jamesh.id.au-20140801110939-lzfql7fk76dt6ckd 128
4launchpad.net/go-xdg/v0 bzr john.lenton@canonical.com-20140208094800-gubd5md7cro3mtxa 104launchpad.net/go-xdg/v0 bzr john.lenton@canonical.com-20140208094800-gubd5md7cro3mtxa 10
5launchpad.net/gocheck bzr gustavo@niemeyer.net-20140225173054-xu9zlkf9kxhvow02 875launchpad.net/gocheck bzr gustavo@niemeyer.net-20140225173054-xu9zlkf9kxhvow02 87
66
=== modified file 'launch_helper/kindpool.go'
--- launch_helper/kindpool.go 2014-07-29 15:24:01 +0000
+++ launch_helper/kindpool.go 2014-08-22 14:47:03 +0000
@@ -72,7 +72,7 @@
72func DefaultLaunchers(log logger.Logger) map[string]HelperLauncher {72func DefaultLaunchers(log logger.Logger) map[string]HelperLauncher {
73 return map[string]HelperLauncher{73 return map[string]HelperLauncher{
74 "click": cual.New(log),74 "click": cual.New(log),
75 "legacy": legacy.New(),75 "legacy": legacy.New(log),
76 }76 }
77}77}
7878
7979
=== modified file 'launch_helper/kindpool_test.go'
--- launch_helper/kindpool_test.go 2014-08-08 09:03:42 +0000
+++ launch_helper/kindpool_test.go 2014-08-22 14:47:03 +0000
@@ -102,16 +102,22 @@
102 return args102 return args
103}103}
104104
105func (s *poolSuite) SetUpSuite(c *C) {
106 xdgCacheHome = c.MkDir
107}
108
109func (s *poolSuite) TearDownSuite(c *C) {
110 xdgCacheHome = xdg.Cache.Home
111}
112
105func (s *poolSuite) SetUpTest(c *C) {113func (s *poolSuite) SetUpTest(c *C) {
106 s.log = helpers.NewTestLogger(c, "debug")114 s.log = helpers.NewTestLogger(c, "debug")
107 s.fakeLauncher = &fakeHelperLauncher{argCh: make(chan [5]string, 10)}115 s.fakeLauncher = &fakeHelperLauncher{argCh: make(chan [5]string, 10)}
108 s.pool = NewHelperPool(map[string]HelperLauncher{"fake": s.fakeLauncher}, s.log)116 s.pool = NewHelperPool(map[string]HelperLauncher{"fake": s.fakeLauncher}, s.log)
109 xdgCacheHome = c.MkDir
110}117}
111118
112func (s *poolSuite) TearDownTest(c *C) {119func (s *poolSuite) TearDownTest(c *C) {
113 s.pool = nil120 s.pool = nil
114 xdgCacheHome = xdg.Cache.Home
115}121}
116122
117func (s *poolSuite) TestDefaultLaunchers(c *C) {123func (s *poolSuite) TestDefaultLaunchers(c *C) {
@@ -379,8 +385,9 @@
379}385}
380386
381func (s *poolSuite) TestGetTempFilename(c *C) {387func (s *poolSuite) TestGetTempFilename(c *C) {
388 tmpDir := c.MkDir()
382 GetTempDir = func(pkgName string) (string, error) {389 GetTempDir = func(pkgName string) (string, error) {
383 return c.MkDir(), nil390 return tmpDir, nil
384 }391 }
385 // restore it when we are done392 // restore it when we are done
386 defer func() {393 defer func() {
387394
=== modified file 'launch_helper/legacy/legacy.go'
--- launch_helper/legacy/legacy.go 2014-07-18 20:45:21 +0000
+++ launch_helper/legacy/legacy.go 2014-08-22 14:47:03 +0000
@@ -18,20 +18,23 @@
18package legacy18package legacy
1919
20import (20import (
21 "io"
21 "os"22 "os"
22 "os/exec"23 "os/exec"
23 "path/filepath"24 "path/filepath"
24 "strconv"25 "strconv"
2526
26 "launchpad.net/ubuntu-push/click"27 "launchpad.net/ubuntu-push/click"
28 "launchpad.net/ubuntu-push/logger"
27)29)
2830
29type legacyHelperLauncher struct {31type legacyHelperLauncher struct {
32 log logger.Logger
30 done func(string)33 done func(string)
31}34}
3235
33func New() *legacyHelperLauncher {36func New(log logger.Logger) *legacyHelperLauncher {
34 return new(legacyHelperLauncher)37 return &legacyHelperLauncher{log: log}
35}38}
3639
37func (lhl *legacyHelperLauncher) InstallObserver(done func(string)) error {40func (lhl *legacyHelperLauncher) InstallObserver(done func(string)) error {
@@ -50,9 +53,10 @@
50func (lhl *legacyHelperLauncher) Launch(_, progname, f1, f2 string) (string, error) {53func (lhl *legacyHelperLauncher) Launch(_, progname, f1, f2 string) (string, error) {
51 cmd := exec.Command(progname, f1, f2)54 cmd := exec.Command(progname, f1, f2)
52 cmd.Stdin = nil55 cmd.Stdin = nil
53 cmd.Stdout = nil56 var stdout_r, stdout_w = io.Pipe()
54 cmd.Stderr = nil57 var stderr_r, stderr_w = io.Pipe()
5558 cmd.Stdout = stdout_w
59 cmd.Stderr = stderr_w
56 err := cmd.Start()60 err := cmd.Start()
57 if err != nil {61 if err != nil {
58 return "", err62 return "", err
@@ -63,7 +67,17 @@
63 }67 }
64 id := strconv.FormatInt((int64)(proc.Pid), 36)68 id := strconv.FormatInt((int64)(proc.Pid), 36)
65 go func() {69 go func() {
66 proc.Wait()70 state, p_err := proc.Wait()
71 if p_err != nil || !state.Success() {
72 // Helper failed, log output
73 var data []byte
74 stdout_w.Close()
75 stdout_r.Read(data)
76 lhl.log.Errorf("Legacy helper failed. Stdout: %s", data)
77 stderr_w.Close()
78 stderr_r.Read(data)
79 lhl.log.Errorf("Legacy helper failed. Stderr: %s", data)
80 }
67 lhl.done(id)81 lhl.done(id)
68 }()82 }()
6983
7084
=== modified file 'launch_helper/legacy/legacy_test.go'
--- launch_helper/legacy/legacy_test.go 2014-07-18 20:45:21 +0000
+++ launch_helper/legacy/legacy_test.go 2014-08-22 14:47:03 +0000
@@ -32,7 +32,7 @@
32 select {32 select {
33 case s := <-ch:33 case s := <-ch:
34 return s34 return s
35 case <-time.After(time.Second):35 case <-time.After(5 * time.Second):
36 c.Fatal("timed out waiting for value")36 c.Fatal("timed out waiting for value")
37 return ""37 return ""
38 }38 }
@@ -42,12 +42,14 @@
4242
43type legacySuite struct {43type legacySuite struct {
44 lhl *legacyHelperLauncher44 lhl *legacyHelperLauncher
45 log *helpers.TestLogger
45}46}
4647
47var _ = Suite(&legacySuite{})48var _ = Suite(&legacySuite{})
4849
49func (ls *legacySuite) SetUpTest(c *C) {50func (ls *legacySuite) SetUpTest(c *C) {
50 ls.lhl = New()51 ls.log = helpers.NewTestLogger(c, "info")
52 ls.lhl = New(ls.log)
51}53}
5254
53func (ls *legacySuite) TestInstallObserver(c *C) {55func (ls *legacySuite) TestInstallObserver(c *C) {
@@ -94,12 +96,24 @@
94 c.Assert(err, NotNil)96 c.Assert(err, NotNil)
95}97}
9698
99func (ls *legacySuite) TestHelperFails(c *C) {
100 ch := make(chan string, 1)
101 c.Assert(ls.lhl.InstallObserver(func(id string) { ch <- id }), IsNil)
102
103 _, err := ls.lhl.Launch("", "/bin/false", "", "")
104 c.Assert(err, IsNil)
105
106 takeNext(ch, c)
107 c.Check(ls.log.Captured(), Matches, "(?s).*Legacy helper failed.*")
108}
109
97func (ls *legacySuite) TestStop(c *C) {110func (ls *legacySuite) TestStop(c *C) {
98 ch := make(chan string, 1)111 ch := make(chan string, 1)
99 c.Assert(ls.lhl.InstallObserver(func(id string) { ch <- id }), IsNil)112 c.Assert(ls.lhl.InstallObserver(func(id string) { ch <- id }), IsNil)
100113
101 exe := helpers.ScriptAbsPath("slow-helper.sh")114 exe := helpers.ScriptAbsPath("slow-helper.sh")
102 id, err := ls.lhl.Launch("", exe, "", "")115 id, err := ls.lhl.Launch("", exe, "", "")
116 c.Assert(err, IsNil)
103117
104 err = ls.lhl.Stop("", "===")118 err = ls.lhl.Stop("", "===")
105 c.Check(err, NotNil) // not a valid id119 c.Check(err, NotNil) // not a valid id
106120
=== modified file 'server/acceptance/acceptanceclient.go'
--- server/acceptance/acceptanceclient.go 2014-06-05 09:32:43 +0000
+++ server/acceptance/acceptanceclient.go 2014-08-22 14:47:03 +0000
@@ -19,9 +19,7 @@
1919
20import (20import (
21 "crypto/tls"21 "crypto/tls"
22 "crypto/x509"
23 "encoding/json"22 "encoding/json"
24 "errors"
25 "fmt"23 "fmt"
26 "net"24 "net"
27 "strings"25 "strings"
@@ -40,35 +38,36 @@
40 ImageChannel string38 ImageChannel string
41 ServerAddr string39 ServerAddr string
42 ExchangeTimeout time.Duration40 ExchangeTimeout time.Duration
43 CertPEMBlock []byte
44 ReportPings bool41 ReportPings bool
45 Levels map[string]int6442 Levels map[string]int64
46 Insecure bool // don't verify certs43 TLSConfig *tls.Config
47 Prefix string // prefix for events44 Prefix string // prefix for events
48 Auth string45 Auth string
49 // connection46 // connection
50 Connection net.Conn47 Connection net.Conn
51}48}
5249
53// Dial connects to a server using the configuration in the ClientSession50// Dial connects to a server using the configuration in the
54// and sets up the connection.51// ClientSession and sets up the connection.
55func (sess *ClientSession) Dial() error {52func (sess *ClientSession) Dial() error {
56 conn, err := net.DialTimeout("tcp", sess.ServerAddr, sess.ExchangeTimeout)53 conn, err := net.DialTimeout("tcp", sess.ServerAddr, sess.ExchangeTimeout)
57 if err != nil {54 if err != nil {
58 return err55 return err
59 }56 }
60 tlsConfig := &tls.Config{}57 sess.TLSWrapAndSet(conn)
61 if sess.CertPEMBlock != nil {58 return nil
62 cp := x509.NewCertPool()59}
63 ok := cp.AppendCertsFromPEM(sess.CertPEMBlock)60
64 if !ok {61// TLSWrapAndSet wraps a socket connection in tls and sets it as
65 return errors.New("dial: could not parse certificate")62// session.Connection. For use instead of Dial().
66 }63func (sess *ClientSession) TLSWrapAndSet(conn net.Conn) {
67 tlsConfig.RootCAs = cp64 var tlsConfig *tls.Config
65 if sess.TLSConfig != nil {
66 tlsConfig = sess.TLSConfig
67 } else {
68 tlsConfig = &tls.Config{}
68 }69 }
69 tlsConfig.InsecureSkipVerify = sess.Insecure
70 sess.Connection = tls.Client(conn, tlsConfig)70 sess.Connection = tls.Client(conn, tlsConfig)
71 return nil
72}71}
7372
74type serverMsg struct {73type serverMsg struct {
7574
=== added file 'server/acceptance/cmd/acceptanceclient.go'
--- server/acceptance/cmd/acceptanceclient.go 1970-01-01 00:00:00 +0000
+++ server/acceptance/cmd/acceptanceclient.go 2014-08-22 14:47:03 +0000
@@ -0,0 +1,54 @@
1/*
2 Copyright 2013-2014 Canonical Ltd.
3
4 This program is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License version 3, as published
6 by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranties of
10 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17// acceptanceclient command for playing.
18package main
19
20import (
21 "log"
22 "os/exec"
23 "strings"
24
25 "launchpad.net/ubuntu-push/server/acceptance"
26 "launchpad.net/ubuntu-push/server/acceptance/kit"
27)
28
29type configuration struct {
30 kit.Configuration
31 AuthHelper string `json:"auth_helper"`
32 WaitFor string `json:"wait_for"`
33}
34
35func main() {
36 kit.Defaults["auth_helper"] = ""
37 kit.Defaults["wait_for"] = ""
38 cfg := &configuration{}
39 kit.CliLoop(cfg, &cfg.Configuration, func(session *acceptance.ClientSession, cfgDir string) {
40 log.Printf("with: %#v", session)
41 }, func(url string) string {
42 if cfg.AuthHelper == "" {
43 return ""
44 }
45 auth, err := exec.Command(cfg.AuthHelper, url).Output()
46 if err != nil {
47 log.Fatalf("auth helper: %v", err)
48 }
49 return strings.TrimSpace(string(auth))
50 }, func() string {
51 return cfg.WaitFor
52 }, func() {
53 })
54}
055
=== added directory 'server/acceptance/kit'
=== added file 'server/acceptance/kit/api.go'
--- server/acceptance/kit/api.go 1970-01-01 00:00:00 +0000
+++ server/acceptance/kit/api.go 2014-08-22 14:47:03 +0000
@@ -0,0 +1,82 @@
1/*
2 Copyright 2013-2014 Canonical Ltd.
3
4 This program is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License version 3, as published
6 by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranties of
10 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17// Package kit contains reusable building blocks for acceptance.
18package kit
19
20import (
21 "bytes"
22 "crypto/tls"
23 "encoding/json"
24 "errors"
25 "io/ioutil"
26 "net/http"
27)
28
29// APIClient helps making api requests.
30type APIClient struct {
31 ServerAPIURL string
32 // hook to adjust requests
33 MassageRequest func(req *http.Request, message interface{}) *http.Request
34 // other state
35 httpClient *http.Client
36}
37
38// SetupClient sets up the http client to make requests.
39func (api *APIClient) SetupClient(tlsConfig *tls.Config) {
40 api.httpClient = &http.Client{
41 Transport: &http.Transport{TLSClientConfig: tlsConfig},
42 }
43}
44
45var ErrNOk = errors.New("not ok")
46
47// Post a API request.
48func (api *APIClient) PostRequest(path string, message interface{}) (map[string]interface{}, error) {
49 packedMessage, err := json.Marshal(message)
50 if err != nil {
51 panic(err)
52 }
53 reader := bytes.NewReader(packedMessage)
54
55 url := api.ServerAPIURL + path
56 request, _ := http.NewRequest("POST", url, reader)
57 request.ContentLength = int64(reader.Len())
58 request.Header.Set("Content-Type", "application/json")
59
60 if api.MassageRequest != nil {
61 request = api.MassageRequest(request, message)
62 }
63
64 resp, err := api.httpClient.Do(request)
65 if err != nil {
66 return nil, err
67 }
68 defer resp.Body.Close()
69 body, err := ioutil.ReadAll(resp.Body)
70 if err != nil {
71 return nil, err
72 }
73 var res map[string]interface{}
74 err = json.Unmarshal(body, &res)
75 if err != nil {
76 return nil, err
77 }
78 if ok, _ := res["ok"].(bool); !ok {
79 return res, ErrNOk
80 }
81 return res, nil
82}
083
=== renamed file 'server/acceptance/cmd/acceptanceclient.go' => 'server/acceptance/kit/cliloop.go'
--- server/acceptance/cmd/acceptanceclient.go 2014-07-11 21:24:21 +0000
+++ server/acceptance/kit/cliloop.go 2014-08-22 14:47:03 +0000
@@ -14,15 +14,13 @@
14 with this program. If not, see <http://www.gnu.org/licenses/>.14 with this program. If not, see <http://www.gnu.org/licenses/>.
15*/15*/
1616
17// acceptanceclient command for playing.17package kit
18package main
1918
20import (19import (
21 "flag"20 "flag"
22 "fmt"21 "fmt"
23 "log"22 "log"
24 "os"23 "os"
25 "os/exec"
26 "path/filepath"24 "path/filepath"
27 "regexp"25 "regexp"
28 "strings"26 "strings"
@@ -32,27 +30,58 @@
32 "launchpad.net/ubuntu-push/server/acceptance"30 "launchpad.net/ubuntu-push/server/acceptance"
33)31)
3432
35var (33type Configuration struct {
36 insecureFlag = flag.Bool("insecure", false, "disable checking of server certificate and hostname")
37 reportPingsFlag = flag.Bool("reportPings", true, "report each Ping from the server")
38 deviceModel = flag.String("model", "?", "device image model")
39 imageChannel = flag.String("imageChannel", "?", "image channel")
40)
41
42type configuration struct {
43 // session configuration34 // session configuration
44 ExchangeTimeout config.ConfigTimeDuration `json:"exchange_timeout"`35 ExchangeTimeout config.ConfigTimeDuration `json:"exchange_timeout"`
45 // server connection config36 // server connection config
46 Addr config.ConfigHostPort37 Target string `json:"target"`
47 CertPEMFile string `json:"cert_pem_file"`38 Addr config.ConfigHostPort `json:"addr"`
48 AuthHelper string `json:"auth_helper"`39 CertPEMFile string `json:"cert_pem_file"`
49 RunTimeout config.ConfigTimeDuration `json:"run_timeout"`40 Insecure bool `json:"insecure" help:"disable checking of server certificate and hostname"`
50 WaitFor string `json:"wait_for"`41 Domain string `json:"domain" help:"domain for tls connect"`
51}42 // run timeout
5243 RunTimeout config.ConfigTimeDuration `json:"run_timeout"`
53func main() {44 // flags
45 ReportPings bool `json:"reportPings" help:"report each Ping from the server"`
46 DeviceModel string `json:"model" help:"device image model"`
47 ImageChannel string `json:"imageChannel" help:"image channel"`
48}
49
50func (cfg *Configuration) PickByTarget(what, productionValue, stagingValue string) (value string) {
51 switch cfg.Target {
52 case "production":
53 value = productionValue
54 case "staging":
55 value = stagingValue
56 case "":
57 log.Fatalf("either %s or target must be given", what)
58 default:
59 log.Fatalf("if specified target should be production|staging")
60 }
61 return
62}
63
64// Control.
65var (
66 Name = "acceptanceclient"
67 Defaults = map[string]interface{}{
68 "target": "",
69 "addr": ":0",
70 "exchange_timeout": "5s",
71 "cert_pem_file": "",
72 "insecure": false,
73 "domain": "",
74 "run_timeout": "0s",
75 "reportPings": true,
76 "model": "?",
77 "imageChannel": "?",
78 }
79)
80
81// CliLoop parses command line arguments and runs a client loop.
82func CliLoop(totalCfg interface{}, cfg *Configuration, onSetup func(sess *acceptance.ClientSession, cfgDir string), auth func(string) string, waitFor func() string, onConnect func()) {
54 flag.Usage = func() {83 flag.Usage = func() {
55 fmt.Fprintf(os.Stderr, "Usage: acceptancclient [options] <device id>\n")84 fmt.Fprintf(os.Stderr, "Usage: %s [options] <device id>\n", Name)
56 flag.PrintDefaults()85 flag.PrintDefaults()
57 }86 }
58 missingArg := func(what string) {87 missingArg := func(what string) {
@@ -60,14 +89,7 @@
60 flag.Usage()89 flag.Usage()
61 os.Exit(2)90 os.Exit(2)
62 }91 }
63 cfg := &configuration{}92 err := config.ReadFilesDefaults(totalCfg, Defaults, "<flags>")
64 err := config.ReadFilesDefaults(cfg, map[string]interface{}{
65 "exchange_timeout": "5s",
66 "cert_pem_file": "",
67 "auth_helper": "",
68 "run_timeout": "0s",
69 "wait_for": "",
70 }, "<flags>")
71 if err != nil {93 if err != nil {
72 log.Fatalf("reading config: %v", err)94 log.Fatalf("reading config: %v", err)
73 }95 }
@@ -76,36 +98,34 @@
76 case narg < 1:98 case narg < 1:
77 missingArg("device-id")99 missingArg("device-id")
78 }100 }
101 addr := ""
102 if cfg.Addr == ":0" {
103 addr = cfg.PickByTarget("addr", "push-delivery.ubuntu.com:443",
104 "push-delivery.staging.ubuntu.com:443")
105 } else {
106 addr = cfg.Addr.HostPort()
107 }
79 session := &acceptance.ClientSession{108 session := &acceptance.ClientSession{
80 ExchangeTimeout: cfg.ExchangeTimeout.TimeDuration(),109 ExchangeTimeout: cfg.ExchangeTimeout.TimeDuration(),
81 ServerAddr: cfg.Addr.HostPort(),110 ServerAddr: addr,
82 DeviceId: flag.Arg(0),111 DeviceId: flag.Arg(0),
83 // flags112 // flags
84 Model: *deviceModel,113 Model: cfg.DeviceModel,
85 ImageChannel: *imageChannel,114 ImageChannel: cfg.ImageChannel,
86 ReportPings: *reportPingsFlag,115 ReportPings: cfg.ReportPings,
87 Insecure: *insecureFlag,116 }
88 }117 cfgDir := filepath.Dir(flag.Lookup("cfg@").Value.String())
89 log.Printf("with: %#v", session)118 onSetup(session, cfgDir)
90 if !*insecureFlag && cfg.CertPEMFile != "" {119 session.TLSConfig, err = MakeTLSConfig(cfg.Domain, cfg.Insecure, cfg.CertPEMFile, cfgDir)
91 cfgDir := filepath.Dir(flag.Lookup("cfg@").Value.String())120 if err != nil {
92 log.Printf("cert: %v relToDir: %v", cfg.CertPEMFile, cfgDir)121 log.Fatalf("tls config: %v", err)
93 session.CertPEMBlock, err = config.LoadFile(cfg.CertPEMFile, cfgDir)122 }
94 if err != nil {123 session.Auth = auth("https://push.ubuntu.com/")
95 log.Fatalf("reading CertPEMFile: %v", err)
96 }
97 }
98 if len(cfg.AuthHelper) != 0 {
99 auth, err := exec.Command(cfg.AuthHelper, "https://push.ubuntu.com/").Output()
100 if err != nil {
101 log.Fatalf("auth helper: %v", err)
102 }
103 session.Auth = strings.TrimSpace(string(auth))
104 }
105 var waitForRegexp *regexp.Regexp124 var waitForRegexp *regexp.Regexp
106 if cfg.WaitFor != "" {125 waitForStr := waitFor()
126 if waitForStr != "" {
107 var err error127 var err error
108 waitForRegexp, err = regexp.Compile(cfg.WaitFor)128 waitForRegexp, err = regexp.Compile(waitForStr)
109 if err != nil {129 if err != nil {
110 log.Fatalf("wait_for regexp: %v", err)130 log.Fatalf("wait_for regexp: %v", err)
111 }131 }
@@ -118,6 +138,9 @@
118 go func() {138 go func() {
119 for {139 for {
120 ev := <-events140 ev := <-events
141 if strings.HasPrefix(ev, "connected") {
142 onConnect()
143 }
121 if waitForRegexp != nil && waitForRegexp.MatchString(ev) {144 if waitForRegexp != nil && waitForRegexp.MatchString(ev) {
122 log.Println("<matching-event>:", ev)145 log.Println("<matching-event>:", ev)
123 os.Exit(0)146 os.Exit(0)
124147
=== added file 'server/acceptance/kit/helpers.go'
--- server/acceptance/kit/helpers.go 1970-01-01 00:00:00 +0000
+++ server/acceptance/kit/helpers.go 2014-08-22 14:47:03 +0000
@@ -0,0 +1,46 @@
1/*
2 Copyright 2013-2014 Canonical Ltd.
3
4 This program is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License version 3, as published
6 by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranties of
10 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17package kit
18
19import (
20 "crypto/tls"
21 "crypto/x509"
22 "fmt"
23
24 "launchpad.net/ubuntu-push/config"
25)
26
27// MakeTLSConfig makes a tls.Config, optionally reading a cert from
28// disk, possibly relative to relDir.
29func MakeTLSConfig(domain string, insecure bool, certPEMFile string, relDir string) (*tls.Config, error) {
30 tlsConfig := &tls.Config{}
31 tlsConfig.ServerName = domain
32 tlsConfig.InsecureSkipVerify = insecure
33 if !insecure && certPEMFile != "" {
34 certPEMBlock, err := config.LoadFile(certPEMFile, relDir)
35 if err != nil {
36 return nil, fmt.Errorf("reading cert: %v", err)
37 }
38 cp := x509.NewCertPool()
39 ok := cp.AppendCertsFromPEM(certPEMBlock)
40 if !ok {
41 return nil, fmt.Errorf("could not parse certificate")
42 }
43 tlsConfig.RootCAs = cp
44 }
45 return tlsConfig, nil
46}
047
=== modified file 'server/acceptance/suites/broadcast.go'
--- server/acceptance/suites/broadcast.go 2014-06-25 11:00:15 +0000
+++ server/acceptance/suites/broadcast.go 2014-08-22 14:47:03 +0000
@@ -41,8 +41,7 @@
41 ExpireOn: future,41 ExpireOn: future,
42 Data: json.RawMessage(`{"img1/m1": 42}`),42 Data: json.RawMessage(`{"img1/m1": 42}`),
43 })43 })
44 c.Assert(err, IsNil)44 c.Assert(err, IsNil, Commentf("%v", got))
45 c.Assert(got, Matches, OK)
46 c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`)45 c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`)
47 stop()46 stop()
48 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)47 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)
@@ -56,14 +55,13 @@
56 ExpireOn: future,55 ExpireOn: future,
57 Data: json.RawMessage(`{"img1/m2": 10}`),56 Data: json.RawMessage(`{"img1/m2": 10}`),
58 })57 })
59 c.Assert(err, IsNil)58 c.Assert(err, IsNil, Commentf("%v", got))
60 got, err = s.PostRequest("/broadcast", &api.Broadcast{59 got, err = s.PostRequest("/broadcast", &api.Broadcast{
61 Channel: "system",60 Channel: "system",
62 ExpireOn: future,61 ExpireOn: future,
63 Data: json.RawMessage(`{"img1/m1": 20}`),62 Data: json.RawMessage(`{"img1/m1": 20}`),
64 })63 })
65 c.Assert(err, IsNil)64 c.Assert(err, IsNil, Commentf("%v", got))
66 c.Assert(got, Matches, OK)
67 c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"img1/m1":20}]`)65 c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"img1/m1":20}]`)
68 stop()66 stop()
69 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)67 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)
@@ -77,8 +75,7 @@
77 ExpireOn: future,75 ExpireOn: future,
78 Data: json.RawMessage(`{"img1/m1": 1}`),76 Data: json.RawMessage(`{"img1/m1": 1}`),
79 })77 })
80 c.Assert(err, IsNil)78 c.Assert(err, IsNil, Commentf("%v", got))
81 c.Assert(got, Matches, OK)
8279
83 events, errCh, stop := s.StartClient(c, "DEVB", nil)80 events, errCh, stop := s.StartClient(c, "DEVB", nil)
84 // gettting pending on connect81 // gettting pending on connect
@@ -97,8 +94,7 @@
97 ExpireOn: future,94 ExpireOn: future,
98 Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)),95 Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)),
99 })96 })
100 c.Assert(err, IsNil)97 c.Assert(err, IsNil, Commentf("%v", got))
101 c.Assert(got, Matches, OK)
102 }98 }
10399
104 events, errCh, stop := s.StartClient(c, "DEVC", nil)100 events, errCh, stop := s.StartClient(c, "DEVC", nil)
@@ -130,8 +126,7 @@
130 ExpireOn: future,126 ExpireOn: future,
131 Data: json.RawMessage(`{"img1/m1": 42}`),127 Data: json.RawMessage(`{"img1/m1": 42}`),
132 })128 })
133 c.Assert(err, IsNil)129 c.Assert(err, IsNil, Commentf("%v", got))
134 c.Assert(got, Matches, OK)
135 c.Check(NextEvent(events1, errCh1), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`)130 c.Check(NextEvent(events1, errCh1), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`)
136 c.Check(NextEvent(events2, errCh2), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`)131 c.Check(NextEvent(events2, errCh2), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`)
137 stop1()132 stop1()
@@ -149,8 +144,7 @@
149 ExpireOn: future,144 ExpireOn: future,
150 Data: json.RawMessage(`{"img1/m1": 1}`),145 Data: json.RawMessage(`{"img1/m1": 1}`),
151 })146 })
152 c.Assert(err, IsNil)147 c.Assert(err, IsNil, Commentf("%v", got))
153 c.Assert(got, Matches, OK)
154 c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":1}]`)148 c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":1}]`)
155 stop()149 stop()
156 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)150 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)
@@ -161,8 +155,7 @@
161 ExpireOn: future,155 ExpireOn: future,
162 Data: json.RawMessage(`{"img1/m1": 2}`),156 Data: json.RawMessage(`{"img1/m1": 2}`),
163 })157 })
164 c.Assert(err, IsNil)158 c.Assert(err, IsNil, Commentf("%v", got))
165 c.Assert(got, Matches, OK)
166 // reconnect, provide levels, get only later notification159 // reconnect, provide levels, get only later notification
167 events, errCh, stop = s.StartClient(c, "DEVD", map[string]int64{160 events, errCh, stop = s.StartClient(c, "DEVD", map[string]int64{
168 protocol.SystemChannelId: 1,161 protocol.SystemChannelId: 1,
@@ -180,15 +173,13 @@
180 ExpireOn: future,173 ExpireOn: future,
181 Data: json.RawMessage(`{"img1/m1": 1}`),174 Data: json.RawMessage(`{"img1/m1": 1}`),
182 })175 })
183 c.Assert(err, IsNil)176 c.Assert(err, IsNil, Commentf("%v", got))
184 c.Assert(got, Matches, OK)
185 got, err = s.PostRequest("/broadcast", &api.Broadcast{177 got, err = s.PostRequest("/broadcast", &api.Broadcast{
186 Channel: "system",178 Channel: "system",
187 ExpireOn: future,179 ExpireOn: future,
188 Data: json.RawMessage(`{"img1/m1": 2}`),180 Data: json.RawMessage(`{"img1/m1": 2}`),
189 })181 })
190 c.Assert(err, IsNil)182 c.Assert(err, IsNil, Commentf("%v", got))
191 c.Assert(got, Matches, OK)
192183
193 events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{184 events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{
194 protocol.SystemChannelId: 10,185 protocol.SystemChannelId: 10,
@@ -219,15 +210,13 @@
219 ExpireOn: future,210 ExpireOn: future,
220 Data: json.RawMessage(`{"img1/m1": 1}`),211 Data: json.RawMessage(`{"img1/m1": 1}`),
221 })212 })
222 c.Assert(err, IsNil)213 c.Assert(err, IsNil, Commentf("%v", got))
223 c.Assert(got, Matches, OK)
224 got, err = s.PostRequest("/broadcast", &api.Broadcast{214 got, err = s.PostRequest("/broadcast", &api.Broadcast{
225 Channel: "system",215 Channel: "system",
226 ExpireOn: future,216 ExpireOn: future,
227 Data: json.RawMessage(`{"img1/m1": 2}`),217 Data: json.RawMessage(`{"img1/m1": 2}`),
228 })218 })
229 c.Assert(err, IsNil)219 c.Assert(err, IsNil, Commentf("%v", got))
230 c.Assert(got, Matches, OK)
231220
232 events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{221 events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{
233 protocol.SystemChannelId: -10,222 protocol.SystemChannelId: -10,
@@ -246,15 +235,13 @@
246 ExpireOn: future,235 ExpireOn: future,
247 Data: json.RawMessage(`{"img1/m1": 1}`),236 Data: json.RawMessage(`{"img1/m1": 1}`),
248 })237 })
249 c.Assert(err, IsNil)238 c.Assert(err, IsNil, Commentf("%v", got))
250 c.Assert(got, Matches, OK)
251 got, err = s.PostRequest("/broadcast", &api.Broadcast{239 got, err = s.PostRequest("/broadcast", &api.Broadcast{
252 Channel: "system",240 Channel: "system",
253 ExpireOn: time.Now().Add(1 * time.Second).Format(time.RFC3339),241 ExpireOn: time.Now().Add(1 * time.Second).Format(time.RFC3339),
254 Data: json.RawMessage(`{"img1/m1": 2}`),242 Data: json.RawMessage(`{"img1/m1": 2}`),
255 })243 })
256 c.Assert(err, IsNil)244 c.Assert(err, IsNil, Commentf("%v", got))
257 c.Assert(got, Matches, OK)
258245
259 time.Sleep(2 * time.Second)246 time.Sleep(2 * time.Second)
260 // second broadcast is expired247 // second broadcast is expired
261248
=== modified file 'server/acceptance/suites/suite.go'
--- server/acceptance/suites/suite.go 2014-06-25 11:00:15 +0000
+++ server/acceptance/suites/suite.go 2014-08-22 14:47:03 +0000
@@ -18,13 +18,9 @@
18package suites18package suites
1919
20import (20import (
21 "bytes"
22 "encoding/json"
23 "flag"21 "flag"
24 "fmt"22 "fmt"
25 "io/ioutil"
26 "net"23 "net"
27 "net/http"
28 "os"24 "os"
29 "runtime"25 "runtime"
30 "time"26 "time"
@@ -32,6 +28,7 @@
32 . "launchpad.net/gocheck"28 . "launchpad.net/gocheck"
3329
34 "launchpad.net/ubuntu-push/server/acceptance"30 "launchpad.net/ubuntu-push/server/acceptance"
31 "launchpad.net/ubuntu-push/server/acceptance/kit"
35 helpers "launchpad.net/ubuntu-push/testing"32 helpers "launchpad.net/ubuntu-push/testing"
36)33)
3734
@@ -84,14 +81,10 @@
84 StartServer func(c *C, s *AcceptanceSuite, handle *ServerHandle)81 StartServer func(c *C, s *AcceptanceSuite, handle *ServerHandle)
85 // populated by StartServer82 // populated by StartServer
86 ServerHandle83 ServerHandle
87 ServerAPIURL string84 kit.APIClient // has ServerAPIURL
88 // KillGroup should be populated by StartServer with functions85 // KillGroup should be populated by StartServer with functions
89 // to kill the server process86 // to kill the server process
90 KillGroup map[string]func(os.Signal)87 KillGroup map[string]func(os.Signal)
91 // hook to adjust requests
92 MassageRequest func(req *http.Request, message interface{}) *http.Request
93 // other state
94 httpClient *http.Client
95}88}
9689
97// Start a new server for each test.90// Start a new server for each test.
@@ -101,7 +94,7 @@
101 c.Assert(s.ServerHandle.ServerEvents, NotNil)94 c.Assert(s.ServerHandle.ServerEvents, NotNil)
102 c.Assert(s.ServerHandle.ServerAddr, Not(Equals), "")95 c.Assert(s.ServerHandle.ServerAddr, Not(Equals), "")
103 c.Assert(s.ServerAPIURL, Not(Equals), "")96 c.Assert(s.ServerAPIURL, Not(Equals), "")
104 s.httpClient = &http.Client{}97 s.SetupClient(nil)
105}98}
10699
107func (s *AcceptanceSuite) TearDownTest(c *C) {100func (s *AcceptanceSuite) TearDownTest(c *C) {
@@ -110,45 +103,19 @@
110 }103 }
111}104}
112105
113// Post a API request.
114func (s *AcceptanceSuite) PostRequest(path string, message interface{}) (string, error) {
115 packedMessage, err := json.Marshal(message)
116 if err != nil {
117 panic(err)
118 }
119 reader := bytes.NewReader(packedMessage)
120
121 url := s.ServerAPIURL + path
122 request, _ := http.NewRequest("POST", url, reader)
123 request.ContentLength = int64(reader.Len())
124 request.Header.Set("Content-Type", "application/json")
125
126 if s.MassageRequest != nil {
127 request = s.MassageRequest(request, message)
128 }
129
130 resp, err := s.httpClient.Do(request)
131 if err != nil {
132 panic(err)
133 }
134 defer resp.Body.Close()
135 body, err := ioutil.ReadAll(resp.Body)
136 return string(body), err
137}
138
139func testClientSession(addr string, deviceId, model, imageChannel string, reportPings bool) *acceptance.ClientSession {106func testClientSession(addr string, deviceId, model, imageChannel string, reportPings bool) *acceptance.ClientSession {
140 certPEMBlock, err := ioutil.ReadFile(helpers.SourceRelative("../ssl/testing.cert"))107 tlsConfig, err := kit.MakeTLSConfig("", false, helpers.SourceRelative("../ssl/testing.cert"), "")
141 if err != nil {108 if err != nil {
142 panic(fmt.Sprintf("could not read ssl/testing.cert: %v", err))109 panic(fmt.Sprintf("could not read ssl/testing.cert: %v", err))
143 }110 }
144 return &acceptance.ClientSession{111 return &acceptance.ClientSession{
145 ExchangeTimeout: 100 * time.Millisecond,112 ExchangeTimeout: 100 * time.Millisecond,
146 ServerAddr: addr,113 ServerAddr: addr,
147 CertPEMBlock: certPEMBlock,
148 DeviceId: deviceId,114 DeviceId: deviceId,
149 Model: model,115 Model: model,
150 ImageChannel: imageChannel,116 ImageChannel: imageChannel,
151 ReportPings: reportPings,117 ReportPings: reportPings,
118 TLSConfig: tlsConfig,
152 }119 }
153}120}
154121
@@ -198,5 +165,3 @@
198165
199// Long after the end of the tests.166// Long after the end of the tests.
200var future = time.Now().Add(9 * time.Hour).Format(time.RFC3339)167var future = time.Now().Add(9 * time.Hour).Format(time.RFC3339)
201
202const OK = `.*"ok":true.*`
203168
=== modified file 'server/acceptance/suites/unicast.go'
--- server/acceptance/suites/unicast.go 2014-07-14 15:23:17 +0000
+++ server/acceptance/suites/unicast.go 2014-08-22 14:47:03 +0000
@@ -23,6 +23,7 @@
2323
24 . "launchpad.net/gocheck"24 . "launchpad.net/gocheck"
2525
26 "launchpad.net/ubuntu-push/server/acceptance/kit"
26 "launchpad.net/ubuntu-push/server/api"27 "launchpad.net/ubuntu-push/server/api"
27)28)
2829
@@ -45,20 +46,15 @@
45 DeviceId: "DEV1",46 DeviceId: "DEV1",
46 AppId: "app1",47 AppId: "app1",
47 })48 })
48 c.Assert(err, IsNil)49 c.Assert(err, IsNil, Commentf("%v", res))
49 c.Assert(res, Matches, OK)
50 var reg map[string]interface{}
51 err = json.Unmarshal([]byte(res), &reg)
52 c.Assert(err, IsNil)
53 events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth)50 events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth)
54 got, err := s.PostRequest("/notify", &api.Unicast{51 got, err := s.PostRequest("/notify", &api.Unicast{
55 Token: reg["token"].(string),52 Token: res["token"].(string),
56 AppId: "app1",53 AppId: "app1",
57 ExpireOn: future,54 ExpireOn: future,
58 Data: json.RawMessage(`{"a": 42}`),55 Data: json.RawMessage(`{"a": 42}`),
59 })56 })
60 c.Assert(err, IsNil)57 c.Assert(err, IsNil, Commentf("%v", got))
61 c.Assert(got, Matches, OK)
62 c.Check(NextEvent(events, errCh), Equals, `unicast app:app1 payload:{"a":42};`)58 c.Check(NextEvent(events, errCh), Equals, `unicast app:app1 payload:{"a":42};`)
63 stop()59 stop()
64 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)60 c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`)
@@ -80,8 +76,7 @@
80 ExpireOn: future,76 ExpireOn: future,
81 Data: json.RawMessage(`{"to": 1}`),77 Data: json.RawMessage(`{"to": 1}`),
82 })78 })
83 c.Assert(err, IsNil)79 c.Assert(err, IsNil, Commentf("%v", got))
84 c.Assert(got, Matches, OK)
85 got, err = s.PostRequest("/notify", &api.Unicast{80 got, err = s.PostRequest("/notify", &api.Unicast{
86 UserId: userId2,81 UserId: userId2,
87 DeviceId: "DEV2",82 DeviceId: "DEV2",
@@ -89,8 +84,7 @@
89 ExpireOn: future,84 ExpireOn: future,
90 Data: json.RawMessage(`{"to": 2}`),85 Data: json.RawMessage(`{"to": 2}`),
91 })86 })
92 c.Assert(err, IsNil)87 c.Assert(err, IsNil, Commentf("%v", got))
93 c.Assert(got, Matches, OK)
94 c.Check(NextEvent(events1, errCh1), Equals, `unicast app:app1 payload:{"to":1};`)88 c.Check(NextEvent(events1, errCh1), Equals, `unicast app:app1 payload:{"to":1};`)
95 c.Check(NextEvent(events2, errCh2), Equals, `unicast app:app1 payload:{"to":2};`)89 c.Check(NextEvent(events2, errCh2), Equals, `unicast app:app1 payload:{"to":2};`)
96 stop1()90 stop1()
@@ -111,8 +105,7 @@
111 ExpireOn: future,105 ExpireOn: future,
112 Data: json.RawMessage(`{"a": 42}`),106 Data: json.RawMessage(`{"a": 42}`),
113 })107 })
114 c.Assert(err, IsNil)108 c.Assert(err, IsNil, Commentf("%v", got))
115 c.Assert(got, Matches, OK)
116109
117 // get pending on connect110 // get pending on connect
118 events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth)111 events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth)
@@ -134,8 +127,7 @@
134 ExpireOn: future,127 ExpireOn: future,
135 Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)),128 Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)),
136 })129 })
137 c.Assert(err, IsNil)130 c.Assert(err, IsNil, Commentf("%v", got))
138 c.Assert(got, Matches, OK)
139 }131 }
140132
141 events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth)133 events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth)
@@ -168,8 +160,7 @@
168 ExpireOn: future,160 ExpireOn: future,
169 Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)),161 Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)),
170 })162 })
171 c.Assert(err, IsNil)163 c.Assert(err, IsNil, Commentf("%v", got))
172 c.Assert(got, Matches, OK)
173 }164 }
174165
175 got, err := s.PostRequest("/notify", &api.Unicast{166 got, err := s.PostRequest("/notify", &api.Unicast{
@@ -179,8 +170,9 @@
179 ExpireOn: future,170 ExpireOn: future,
180 Data: json.RawMessage(fmt.Sprintf(payloadFmt, MaxNotificationsPerApplication)),171 Data: json.RawMessage(fmt.Sprintf(payloadFmt, MaxNotificationsPerApplication)),
181 })172 })
182 c.Assert(err, IsNil)173 c.Assert(err, Equals, kit.ErrNOk, Commentf("%v", got))
183 c.Assert(got, Matches, `.*"error":"too-many-pending".*`)174 errorStr, _ := got["error"].(string)
175 c.Assert(errorStr, Equals, "too-many-pending")
184176
185 // clear all pending177 // clear all pending
186 got, err = s.PostRequest("/notify", &api.Unicast{178 got, err = s.PostRequest("/notify", &api.Unicast{
@@ -191,8 +183,7 @@
191 Data: json.RawMessage(fmt.Sprintf(payloadFmt, 1000)),183 Data: json.RawMessage(fmt.Sprintf(payloadFmt, 1000)),
192 ClearPending: true,184 ClearPending: true,
193 })185 })
194 c.Assert(err, IsNil)186 c.Assert(err, IsNil, Commentf("%v", got))
195 c.Assert(got, Matches, OK)
196187
197 events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth)188 events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth)
198 // getting the 1 pending on connect189 // getting the 1 pending on connect
@@ -214,8 +205,7 @@
214 Data: json.RawMessage(`{"m": 1}`),205 Data: json.RawMessage(`{"m": 1}`),
215 ReplaceTag: "tagFoo",206 ReplaceTag: "tagFoo",
216 })207 })
217 c.Assert(err, IsNil)208 c.Assert(err, IsNil, Commentf("%v", got))
218 c.Assert(got, Matches, OK)
219209
220 // replace210 // replace
221 got, err = s.PostRequest("/notify", &api.Unicast{211 got, err = s.PostRequest("/notify", &api.Unicast{
@@ -226,8 +216,7 @@
226 Data: json.RawMessage(`{"m": 2}`),216 Data: json.RawMessage(`{"m": 2}`),
227 ReplaceTag: "tagFoo",217 ReplaceTag: "tagFoo",
228 })218 })
229 c.Assert(err, IsNil)219 c.Assert(err, IsNil, Commentf("%v", got))
230 c.Assert(got, Matches, OK)
231220
232 events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth)221 events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth)
233 // getting the 1 pending on connect222 // getting the 1 pending on connect

Subscribers

People subscribed via source and target branches