title: Golang test with channels does not exit
body: <p>The following Golang test never exits. I suspect it has something to do with a channel deadlock but being a go-noob, I am not very certain.</p>
  
  <pre><code>const userName = "xxxxxxxxxxxx"
  
  func TestSynchroninze(t *testing.T) {
      c, err := channel.New(github.ChannelName, authToken)
      if err != nil {
          t.Fatalf("Could not create channel: %s", err)
          return
      }
  
      state := channel.NewState(nil)
      ctx := context.Background()
      ctx = context.WithValue(ctx, "userId", userName)
      user := api.User{}
  
      output, errs := c.Synchronize(state, ctx)
  
      if err = &lt;-errs; err != nil {
          t.Fatalf("Error performing synchronize: %s", err)
          return
      }
  
      for o := range output {
          switch oo := o.Data.(type) {
          case api.User:
              user = oo
              glog.Infof("we have a USER %s\n", user)
          default:
              t.Errorf("Encountered unexpected data type: %T", oo)
          }
      }
  }
  </code></pre>
  
  <p>Here are the methods being tested.</p>
  
  <pre><code>type github struct {
      client *api.Client
  }
  
  func newImplementation(t auth.UserToken) implementation.Implementation {
      return &amp;github{client: api.NewClient(t)}
  }
  
  // -------------------------------------------------------------------------------------
  
  const (
      kLastUserFetch = "lastUserFetch"
  )
  
  type synchronizeFunc func(implementation.MutableState, chan *implementation.Output, context.Context) error
  
  // -------------------------------------------------------------------------------------
  
      func (g *github) Synchronize(state implementation.MutableState, ctx context.Context) (&lt;-chan *implementation.Output, &lt;-chan error) {
          output := make(chan *implementation.Output)
          errors := make(chan error, 1) // buffer allows preflight errors
  
          // Close output channels once we're done
          defer func() {
              go func() {
                  // wg.Wait()
  
                  close(errors)
                  close(output)
              }()
          }()
  
          err := g.fetchUser(state, output, ctx)
          if err != nil {
              errors &lt;- err
          }
  
          return output, errors
      }
  
  func (g *github) fetchUser(state implementation.MutableState, output chan *implementation.Output, ctx context.Context) error {
      var err error
  
      var user = api.User{}
      userId, _ := ctx.Value("userId").(string)
      user, err = g.client.GetUser(userId, ctx.Done())
  
      if err == nil {
          glog.Info("No error in fetchUser")
          output &lt;- &amp;implementation.Output{Data: user}
          state.SetTime(kLastUserFetch, time.Now())
      }
  
      return err
  }
  
  func (c *Client) GetUser(id string, quit &lt;-chan struct{}) (user User, err error) {
      // Execute request
      var data []byte
      data, err = c.get("users/"+id, nil, quit)
      glog.Infof("USER DATA %s", data)
  
      // Parse response
      if err == nil &amp;&amp; len(data) &gt; 0 {
          err = json.Unmarshal(data, &amp;user)
  
          data, _ = json.Marshal(user)
      }
  
      return
  }
  </code></pre>
  
  <p>Here is what I see in the console (most of the user details removed)</p>
  
  <pre><code>I1228 13:25:05.291010   21313 client.go:177] GET https://api.github.com/users/xxxxxxxx
  I1228 13:25:06.010085   21313 client.go:36] USER DATA {"login":"xxxxxxxx","id":00000000,"avatar_url":"https://avatars.githubusercontent.com/u/0000000?v=3",...}
  I1228 13:25:06.010357   21313 github.go:90] No error in fetchUser
  </code></pre>
  
  <p>==========EDIT=============</p>
  
  <p>Here is the relevant portion of the <code>api</code> package.</p>
  
  <pre><code>package api
  
  type Client struct {
      authToken auth.UserToken
      http      *http.Client
  }
  
  func NewClient(authToken auth.UserToken) *Client {
      return &amp;Client{
          authToken: authToken,
          http:      auth.NewClient(authToken),
      }
  }
  
  
  
  
  // -------------------------------------------------------------------------------------
  type User struct {
      Id             int    `json:"id,omitempty"`
      Username       string `json:"login,omitempty"`
      Email          string `json:"email,omitempty"`
      FullName       string `json:"name,omitempty"`
      ProfilePicture string `json:"avatar_url,omitempty"`
      Bio            string `json:"bio,omitempty"`
      Website        string `json:"blog,omitempty"`
      Company        string `json:"company,omitempty"`
  }
  </code></pre>
  
  <p>And the <code>channel</code> package</p>
  
  <pre><code>package channel
  
  type Channel struct {
      implementation.Descriptor
      imp implementation.Implementation
  }
  
  // New returns a channel implementation with a given name and auth token.
  func New(name string, token auth.UserToken) (*Channel, error) {
      if desc, ok := implementation.Lookup(name); ok {
          if imp := implementation.New(name, token); imp != nil {
              return &amp;Channel{Descriptor: desc, imp: imp}, nil
          }
      }
  
      return nil, ErrInvalidChannel
  }
  </code></pre>
  
  <p>and the <code>implementation</code> package...</p>
  
  <pre><code>package implementation
  
  import "golang.org/x/net/context"
  
  // -------------------------------------------------------------------------------------
  
  // Implementation is the interface implemented by subpackages.
  type Implementation interface {
      // Synchronize performs a synchronization using the given state. A context parameters
      // is provided to provide cancellation as well as implementation-specific behaviors.
      //
      // If a fatal error occurs (see package error definitions), the state can be discarded
      // to prevent the persistence of an invalid state.
      Synchronize(state MutableState, ctx context.Context) (&lt;-chan *Output, &lt;-chan error)
  
      // FetchDetails gets details for a given timeline item. Any changes to the TimelineItem
      // (including the Meta value) will be persisted.
      FetchDetails(item *TimelineItem, ctx context.Context) (interface{}, error)
  }
  </code></pre>
  
  <p>======Edit #2=======</p>
  
  <p>This is the original <code>Synchronize</code> method. I removed some details in my testing to try and simplify the problem. By removing a <code>go func</code> call, I believe I introduced a new problem which could be confusing things.</p>
  
  <p>Here is the original Synchronize method. There are some things with <code>Wait Groups</code> and a function array containing a single function because this method will eventually be synchronizing multiple functions.</p>
  
  <pre><code>func (g *github) Synchronize(state implementation.MutableState, ctx context.Context) (&lt;-chan *implementation.Output, &lt;-chan error) {
      wg := sync.WaitGroup{}
      output := make(chan *implementation.Output)
      errors := make(chan error, 1) // buffer allows preflight errors
  
      // Close output channels once we're done
      defer func() {
          go func() {
              wg.Wait()
  
              close(errors)
              close(output)
          }()
      }()
  
      // Perform fetch functions in separate routines
      funcs := []synchronizeFunc{
          g.fetchUser,
      }
  
      for _, f := range funcs {
          wg.Add(1)
  
          go func(f synchronizeFunc) {
              defer wg.Done()
  
              if err := f(state, output, ctx); err != nil {
                  errors &lt;- err
              }
          }(f)
      }
  
      glog.Info("after go sync...")
  
      return output, errors
  }
  </code></pre>