veyron/lib/flags: prevent duplicate values being accumulated

- if flag.Parse is called multiple times, the Set methond on
  for each flag will be called multiple times. This change
  prevents duplicate values from being accumulated, which
  seems like a sensible thing to do in any case.

Change-Id: Idca03dc362f48f386aa97a0fcf1945704a6d8bc1
diff --git a/lib/flags/flags.go b/lib/flags/flags.go
index a6d7888..d6a4810 100644
--- a/lib/flags/flags.go
+++ b/lib/flags/flags.go
@@ -54,6 +54,11 @@
 		nsr.isSet = true
 		nsr.roots = []string{}
 	}
+	for _, t := range nsr.roots {
+		if v == t {
+			return nil
+		}
+	}
 	nsr.roots = append(nsr.roots, v)
 	return nil
 }
@@ -158,6 +163,11 @@
 		ip.flags.protocol.String(),
 		ip.validator.String(),
 	}
+	for _, t := range ip.flags.Addrs {
+		if t.Protocol == a.Protocol && t.Address == a.Address {
+			return nil
+		}
+	}
 	ip.flags.Addrs = append(ip.flags.Addrs, a)
 	return nil
 }
diff --git a/lib/flags/flags_test.go b/lib/flags/flags_test.go
index eb712e9..8adaacf 100644
--- a/lib/flags/flags_test.go
+++ b/lib/flags/flags_test.go
@@ -214,3 +214,48 @@
 		}
 	}
 }
+
+func TestDuplicateFlags(t *testing.T) {
+	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Listen)
+	if err := fl.Parse([]string{
+		"--veyron.tcp.address=172.0.0.1:10", "--veyron.tcp.address=172.0.0.1:10", "--veyron.tcp.address=172.0.0.1:34", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=172.0.0.1:10", "--veyron.tcp.address=172.0.0.1:34", "--veyron.tcp.address=172.0.0.1:34"}); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	lf := fl.ListenFlags()
+	if got, want := len(lf.Addrs), 4; got != want {
+		t.Errorf("got %d, want %d", got, want)
+	}
+	expected := flags.ListenAddrs{
+		{"tcp", "172.0.0.1:10"},
+		{"tcp", "172.0.0.1:34"},
+		{"ws", "172.0.0.1:10"},
+		{"ws", "172.0.0.1:34"},
+	}
+	if got, want := lf.Addrs, expected; !reflect.DeepEqual(got, want) {
+		t.Fatalf("got %#v, want %#v", got, want)
+	}
+	if err := fl.Parse([]string{
+		"--veyron.tcp.address=172.0.0.1:10", "--veyron.tcp.address=172.0.0.1:10", "--veyron.tcp.address=172.0.0.1:34", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=172.0.0.1:10", "--veyron.tcp.address=127.0.0.1:34", "--veyron.tcp.address=127.0.0.1:34"}); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	if got, want := len(lf.Addrs), 4; got != want {
+		t.Errorf("got %d, want %d", got, want)
+	}
+	if got, want := lf.Addrs, expected; !reflect.DeepEqual(got, want) {
+		t.Fatalf("got %#v, want %#v", got, want)
+	}
+
+	fl = flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Runtime)
+
+	if err := fl.Parse([]string{"--veyron.namespace.root=ab", "--veyron.namespace.root=xy", "--veyron.namespace.root=ab"}); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+
+	rf := fl.RuntimeFlags()
+	if got, want := len(rf.NamespaceRoots), 2; got != want {
+		t.Errorf("got %d, want %d", got, want)
+	}
+	if got, want := rf.NamespaceRoots, []string{"ab", "xy"}; !reflect.DeepEqual(got, want) {
+		t.Fatalf("got %#v, want %#v", got, want)
+	}
+}