anchor.diff:      request(get, Url, Opts).
   
   post(Url, Opts) ->
  +    ct:pal("POST url=~p, opts=~p", [Url, Opts]),
       request(post, Url, Opts).
   
   request(Method, Url, Opts) ->
  
positive.code:     [{group, v2_canary}
      ,{group, read_only}
      ,{group, disabled}
      ].
  
  init_per_suite(Config) ->
  
negative.code: 
  end_per_testcase(_Case, Config) ->
      Config.
  
  channel_create_with_app_name(Config) ->
      Api = ?config(api, Config) ++ "/channels",
      BasicAuth = ?config(auth, Config),
      ChannelName = ?config(channel_name, Config),
      TokenName = ?config(channel_token, Config),
  
      Channel = logplex_channel:create(ChannelName),
      ChannelId = logplex_channel:id(Channel),
      Token = logplex_token:create(ChannelId, TokenName),
  
      meck:expect(logplex_channel, create, [{[ChannelName], Channel}]),
      meck:expect(logplex_token, create, [{[ChannelId, TokenName], Token}]),
  
      JsonBody = ["{\"name\":\"", ChannelName, "\","
                  "\"tokens\": [\"", TokenName, "\"]}"],
  
      Res = post(Api, [{headers, [{"Authorization", BasicAuth}]},
                       {body, iolist_to_binary(JsonBody)}]),
      201 = proplists:get_value(status_code, Res),
      {struct, Props} = mochijson2:decode(proplists:get_value(body, Res)),
  
      ChannelId = proplists:get_value(<<"channel_id">>, Props),
      {struct, [{TokenName, Token}]} = proplists:get_value(<<"tokens">>, Props),
  
      meck:unload(),
      ok.
  
  v2_canary_session(Config) ->
      Api = ?config(api, Config) ++ "/v2/canary-sessions",
  