1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package systests
5
6import (
7	"fmt"
8	"testing"
9
10	"github.com/keybase/client/go/client"
11	"github.com/keybase/client/go/libkb"
12	keybase1 "github.com/keybase/client/go/protocol/keybase1"
13	"github.com/keybase/client/go/service"
14)
15
16func TestConfigGetAndSet(t *testing.T) {
17	tc := setupTest(t, "stop")
18	defer tc.Cleanup()
19
20	stopCh := make(chan error)
21	svc := service.NewService(tc.G, false)
22	startCh := svc.GetStartChannel()
23	go func() {
24		err := svc.Run()
25		if err != nil {
26			t.Logf("hit an error in Run, which might be masked: %v", err)
27		}
28		stopCh <- err
29	}()
30
31	tc2 := cloneContext(tc)
32	defer tc2.Cleanup()
33
34	<-startCh
35
36	testConfigGetAndSet(t, tc2.G)
37
38	if err := CtlStop(tc2.G); err != nil {
39		t.Fatal(err)
40	}
41
42	// If the server failed, it's also an error
43	if err := <-stopCh; err != nil {
44		t.Fatal(err)
45	}
46}
47
48type configTestUI struct {
49	baseNullUI
50	stdout []string
51	stderr []string
52}
53
54func (c *configTestUI) GetDumbOutputUI() libkb.DumbOutputUI {
55	return c
56}
57
58func (c *configTestUI) Printf(fmtString string, args ...interface{}) (int, error) {
59	return c.PrintfUnescaped(fmtString, args...)
60}
61
62func (c *configTestUI) PrintfUnescaped(fmtString string, args ...interface{}) (int, error) {
63	s := fmt.Sprintf(fmtString, args...)
64	c.stdout = append(c.stdout, s)
65	return 0, nil
66}
67
68func (c *configTestUI) PrintfStderr(fmtString string, args ...interface{}) (int, error) {
69	s := fmt.Sprintf(fmtString, args...)
70	c.stderr = append(c.stderr, s)
71	return 0, nil
72}
73
74func compareLists(t *testing.T, wanted []string, got []string, desc string) {
75	if wanted == nil {
76		return
77	}
78	if len(wanted) != len(got) {
79		t.Fatalf("In list %s: wrong length: wanted %d but got %d", desc, len(wanted), len(got))
80	}
81	for i, s := range wanted {
82		if s != got[i] {
83			t.Fatalf("At element %d of list %s: wanted %q but got %q", i, desc, s, got[i])
84		}
85	}
86}
87
88func testConfigGet(t *testing.T, g *libkb.GlobalContext, path string, stdout []string, stderr []string, wantErr bool) {
89	ctui := configTestUI{}
90	g.SetUI(&ctui)
91	get := client.NewCmdConfigGetRunner(g)
92	get.Path = path
93	err := get.Run()
94	if wantErr && err == nil {
95		t.Fatal("Expected an error")
96	}
97	if !wantErr && err != nil {
98		t.Fatalf("Wanted no error, but got: %v", err)
99	}
100	compareLists(t, stderr, ctui.stderr, "standard error")
101	compareLists(t, stdout, ctui.stdout, "standard output")
102}
103
104func testConfigSet(t *testing.T, g *libkb.GlobalContext, path string, val keybase1.ConfigValue, wantErr bool) {
105	set := client.NewCmdConfigSetRunner(g)
106	set.Path = path
107	set.Value = val
108	err := set.Run()
109	if wantErr && err == nil {
110		t.Fatal("Expected an error")
111	}
112	if !wantErr && err != nil {
113		t.Fatalf("Wanted no error, but got: %v", err)
114	}
115}
116
117func testConfigClear(t *testing.T, g *libkb.GlobalContext, path string, wantErr bool) {
118	set := client.NewCmdConfigSetRunner(g)
119	set.Path = path
120	set.DoClear = true
121	err := set.Run()
122	if wantErr && err == nil {
123		t.Fatal("Expected an error")
124	}
125	if !wantErr && err != nil {
126		t.Fatalf("Wanted no error, but got: %v", err)
127	}
128}
129
130func testConfigGetAndSet(t *testing.T, g *libkb.GlobalContext) {
131	testConfigGet(t, g, "a", []string{}, nil, true)
132	i := 20
133	testConfigSet(t, g, "foo", keybase1.ConfigValue{I: &i}, false)
134	testConfigGet(t, g, "foo", []string{"20\n"}, nil, false)
135	b := false
136	testConfigSet(t, g, "foo", keybase1.ConfigValue{B: &b}, false)
137	testConfigGet(t, g, "foo", []string{"false\n"}, nil, false)
138	s := "bartime"
139	testConfigSet(t, g, "foo.bar", keybase1.ConfigValue{S: &s}, false)
140	testConfigGet(t, g, "foo", []string{"{\"bar\":\"bartime\"}\n"}, nil, false)
141	testConfigSet(t, g, "foo.baz", keybase1.ConfigValue{IsNull: true}, false)
142	testConfigGet(t, g, "foo", []string{"{\"bar\":\"bartime\",\"baz\":null}\n"}, nil, false)
143	o := `
144	    [ { "a" : { "b" : [1,2,3], "c" : true } }, 10, "hi" ]
145	`
146	testConfigSet(t, g, "yo", keybase1.ConfigValue{O: &o}, false)
147	testConfigGet(t, g, "yo.0.a.b", []string{"[1,2,3]\n"}, nil, false)
148	testConfigClear(t, g, "yo.0.a.c", false)
149	testConfigGet(t, g, "", []string{"{\"foo\":{\"bar\":\"bartime\",\"baz\":null},\"yo\":[{\"a\":{\"b\":[1,2,3]}},10,\"hi\"]}\n"}, nil, false)
150}
151