feat(ooapi): add toplevel client and simplify API (#248)

* feat(ooapi): add toplevel client and simplify API

This diff should simplify using ooapi from other packages by
adding more abstraction that wraps the existing code.

Part of https://github.com/ooni/probe/issues/1355.

* fix(ooapi): use correct comment for cloners

See https://github.com/ooni/probe-cli/pull/248#discussion_r590663843

* fix(ooapi): make sure the documentation is current

See https://github.com/ooni/probe-cli/pull/248#discussion_r590665773

* fix(ooapi): automate copying APIs

See https://github.com/ooni/probe-cli/pull/248#discussion_r590665837

* feat(ooapi): add unit tests for clientcall.go

See https://github.com/ooni/probe-cli/pull/248#discussion_r590666297

* fix(ooapi): rewrite integration tests to use toplevel API

See https://github.com/ooni/probe-cli/pull/248#discussion_r590665084
This commit is contained in:
Simone Basso 2021-03-19 09:30:42 +01:00 committed by GitHub
parent c22828d369
commit 28ce79eff1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 2090 additions and 795 deletions

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-03-03 11:48:43.129132377 +0100 CET m=+2.301468593
// 2021-03-10 12:20:35.042573349 +0100 CET m=+0.416591177
// https://curl.haxx.se/ca/cacert.pem
package gocertifi
@ -3241,7 +3241,7 @@ kpzNNIaRkPpkUZ3+/uul9XXeifdy
`
// CACerts builds an X.509 certificate pool containing the
// certificate bundle from https://curl.haxx.se/ca/cacert.pem fetch on 2021-03-03 11:48:43.129132377 +0100 CET m=+2.301468593.
// certificate bundle from https://curl.haxx.se/ca/cacert.pem fetch on 2021-03-10 12:20:35.042573349 +0100 CET m=+0.416591177.
// Returns nil on error along with an appropriate error code.
func CACerts() (*x509.CertPool, error) {
pool := x509.NewCertPool()

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:50.431349269 +0100 CET m=+0.000196051
// 2021-03-10 13:17:31.904167818 +0100 CET m=+0.000077877
package ooapi
@ -12,8 +12,8 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
// CheckReportIDAPI implements the CheckReportID API.
type CheckReportIDAPI struct {
// simpleCheckReportIDAPI implements the CheckReportID API.
type simpleCheckReportIDAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -21,28 +21,28 @@ type CheckReportIDAPI struct {
UserAgent string // optional
}
func (api *CheckReportIDAPI) baseURL() string {
func (api *simpleCheckReportIDAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *CheckReportIDAPI) requestMaker() RequestMaker {
func (api *simpleCheckReportIDAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *CheckReportIDAPI) jsonCodec() JSONCodec {
func (api *simpleCheckReportIDAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *CheckReportIDAPI) httpClient() HTTPClient {
func (api *simpleCheckReportIDAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -50,7 +50,7 @@ func (api *CheckReportIDAPI) httpClient() HTTPClient {
}
// Call calls the CheckReportID API.
func (api *CheckReportIDAPI) Call(ctx context.Context, req *apimodel.CheckReportIDRequest) (*apimodel.CheckReportIDResponse, error) {
func (api *simpleCheckReportIDAPI) Call(ctx context.Context, req *apimodel.CheckReportIDRequest) (*apimodel.CheckReportIDResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -62,8 +62,8 @@ func (api *CheckReportIDAPI) Call(ctx context.Context, req *apimodel.CheckReport
return api.newResponse(api.httpClient().Do(httpReq))
}
// CheckInAPI implements the CheckIn API.
type CheckInAPI struct {
// simpleCheckInAPI implements the CheckIn API.
type simpleCheckInAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -71,28 +71,28 @@ type CheckInAPI struct {
UserAgent string // optional
}
func (api *CheckInAPI) baseURL() string {
func (api *simpleCheckInAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *CheckInAPI) requestMaker() RequestMaker {
func (api *simpleCheckInAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *CheckInAPI) jsonCodec() JSONCodec {
func (api *simpleCheckInAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *CheckInAPI) httpClient() HTTPClient {
func (api *simpleCheckInAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -100,7 +100,7 @@ func (api *CheckInAPI) httpClient() HTTPClient {
}
// Call calls the CheckIn API.
func (api *CheckInAPI) Call(ctx context.Context, req *apimodel.CheckInRequest) (*apimodel.CheckInResponse, error) {
func (api *simpleCheckInAPI) Call(ctx context.Context, req *apimodel.CheckInRequest) (*apimodel.CheckInResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -112,8 +112,8 @@ func (api *CheckInAPI) Call(ctx context.Context, req *apimodel.CheckInRequest) (
return api.newResponse(api.httpClient().Do(httpReq))
}
// LoginAPI implements the Login API.
type LoginAPI struct {
// simpleLoginAPI implements the Login API.
type simpleLoginAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -121,28 +121,28 @@ type LoginAPI struct {
UserAgent string // optional
}
func (api *LoginAPI) baseURL() string {
func (api *simpleLoginAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *LoginAPI) requestMaker() RequestMaker {
func (api *simpleLoginAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *LoginAPI) jsonCodec() JSONCodec {
func (api *simpleLoginAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *LoginAPI) httpClient() HTTPClient {
func (api *simpleLoginAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -150,7 +150,7 @@ func (api *LoginAPI) httpClient() HTTPClient {
}
// Call calls the Login API.
func (api *LoginAPI) Call(ctx context.Context, req *apimodel.LoginRequest) (*apimodel.LoginResponse, error) {
func (api *simpleLoginAPI) Call(ctx context.Context, req *apimodel.LoginRequest) (*apimodel.LoginResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -162,8 +162,8 @@ func (api *LoginAPI) Call(ctx context.Context, req *apimodel.LoginRequest) (*api
return api.newResponse(api.httpClient().Do(httpReq))
}
// MeasurementMetaAPI implements the MeasurementMeta API.
type MeasurementMetaAPI struct {
// simpleMeasurementMetaAPI implements the MeasurementMeta API.
type simpleMeasurementMetaAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -171,28 +171,28 @@ type MeasurementMetaAPI struct {
UserAgent string // optional
}
func (api *MeasurementMetaAPI) baseURL() string {
func (api *simpleMeasurementMetaAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *MeasurementMetaAPI) requestMaker() RequestMaker {
func (api *simpleMeasurementMetaAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *MeasurementMetaAPI) jsonCodec() JSONCodec {
func (api *simpleMeasurementMetaAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *MeasurementMetaAPI) httpClient() HTTPClient {
func (api *simpleMeasurementMetaAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -200,7 +200,7 @@ func (api *MeasurementMetaAPI) httpClient() HTTPClient {
}
// Call calls the MeasurementMeta API.
func (api *MeasurementMetaAPI) Call(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error) {
func (api *simpleMeasurementMetaAPI) Call(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -212,8 +212,8 @@ func (api *MeasurementMetaAPI) Call(ctx context.Context, req *apimodel.Measureme
return api.newResponse(api.httpClient().Do(httpReq))
}
// RegisterAPI implements the Register API.
type RegisterAPI struct {
// simpleRegisterAPI implements the Register API.
type simpleRegisterAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -221,28 +221,28 @@ type RegisterAPI struct {
UserAgent string // optional
}
func (api *RegisterAPI) baseURL() string {
func (api *simpleRegisterAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *RegisterAPI) requestMaker() RequestMaker {
func (api *simpleRegisterAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *RegisterAPI) jsonCodec() JSONCodec {
func (api *simpleRegisterAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *RegisterAPI) httpClient() HTTPClient {
func (api *simpleRegisterAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -250,7 +250,7 @@ func (api *RegisterAPI) httpClient() HTTPClient {
}
// Call calls the Register API.
func (api *RegisterAPI) Call(ctx context.Context, req *apimodel.RegisterRequest) (*apimodel.RegisterResponse, error) {
func (api *simpleRegisterAPI) Call(ctx context.Context, req *apimodel.RegisterRequest) (*apimodel.RegisterResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -262,8 +262,8 @@ func (api *RegisterAPI) Call(ctx context.Context, req *apimodel.RegisterRequest)
return api.newResponse(api.httpClient().Do(httpReq))
}
// TestHelpersAPI implements the TestHelpers API.
type TestHelpersAPI struct {
// simpleTestHelpersAPI implements the TestHelpers API.
type simpleTestHelpersAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -271,28 +271,28 @@ type TestHelpersAPI struct {
UserAgent string // optional
}
func (api *TestHelpersAPI) baseURL() string {
func (api *simpleTestHelpersAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *TestHelpersAPI) requestMaker() RequestMaker {
func (api *simpleTestHelpersAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *TestHelpersAPI) jsonCodec() JSONCodec {
func (api *simpleTestHelpersAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *TestHelpersAPI) httpClient() HTTPClient {
func (api *simpleTestHelpersAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -300,7 +300,7 @@ func (api *TestHelpersAPI) httpClient() HTTPClient {
}
// Call calls the TestHelpers API.
func (api *TestHelpersAPI) Call(ctx context.Context, req *apimodel.TestHelpersRequest) (apimodel.TestHelpersResponse, error) {
func (api *simpleTestHelpersAPI) Call(ctx context.Context, req *apimodel.TestHelpersRequest) (apimodel.TestHelpersResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -312,8 +312,8 @@ func (api *TestHelpersAPI) Call(ctx context.Context, req *apimodel.TestHelpersRe
return api.newResponse(api.httpClient().Do(httpReq))
}
// PsiphonConfigAPI implements the PsiphonConfig API.
type PsiphonConfigAPI struct {
// simplePsiphonConfigAPI implements the PsiphonConfig API.
type simplePsiphonConfigAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -324,8 +324,8 @@ type PsiphonConfigAPI struct {
// WithToken returns a copy of the API where the
// value of the Token field is replaced with token.
func (api *PsiphonConfigAPI) WithToken(token string) PsiphonConfigCaller {
out := &PsiphonConfigAPI{}
func (api *simplePsiphonConfigAPI) WithToken(token string) callerForPsiphonConfigAPI {
out := &simplePsiphonConfigAPI{}
out.BaseURL = api.BaseURL
out.HTTPClient = api.HTTPClient
out.JSONCodec = api.JSONCodec
@ -335,28 +335,28 @@ func (api *PsiphonConfigAPI) WithToken(token string) PsiphonConfigCaller {
return out
}
func (api *PsiphonConfigAPI) baseURL() string {
func (api *simplePsiphonConfigAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *PsiphonConfigAPI) requestMaker() RequestMaker {
func (api *simplePsiphonConfigAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *PsiphonConfigAPI) jsonCodec() JSONCodec {
func (api *simplePsiphonConfigAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *PsiphonConfigAPI) httpClient() HTTPClient {
func (api *simplePsiphonConfigAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -364,7 +364,7 @@ func (api *PsiphonConfigAPI) httpClient() HTTPClient {
}
// Call calls the PsiphonConfig API.
func (api *PsiphonConfigAPI) Call(ctx context.Context, req *apimodel.PsiphonConfigRequest) (apimodel.PsiphonConfigResponse, error) {
func (api *simplePsiphonConfigAPI) Call(ctx context.Context, req *apimodel.PsiphonConfigRequest) (apimodel.PsiphonConfigResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -380,8 +380,8 @@ func (api *PsiphonConfigAPI) Call(ctx context.Context, req *apimodel.PsiphonConf
return api.newResponse(api.httpClient().Do(httpReq))
}
// TorTargetsAPI implements the TorTargets API.
type TorTargetsAPI struct {
// simpleTorTargetsAPI implements the TorTargets API.
type simpleTorTargetsAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -392,8 +392,8 @@ type TorTargetsAPI struct {
// WithToken returns a copy of the API where the
// value of the Token field is replaced with token.
func (api *TorTargetsAPI) WithToken(token string) TorTargetsCaller {
out := &TorTargetsAPI{}
func (api *simpleTorTargetsAPI) WithToken(token string) callerForTorTargetsAPI {
out := &simpleTorTargetsAPI{}
out.BaseURL = api.BaseURL
out.HTTPClient = api.HTTPClient
out.JSONCodec = api.JSONCodec
@ -403,28 +403,28 @@ func (api *TorTargetsAPI) WithToken(token string) TorTargetsCaller {
return out
}
func (api *TorTargetsAPI) baseURL() string {
func (api *simpleTorTargetsAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *TorTargetsAPI) requestMaker() RequestMaker {
func (api *simpleTorTargetsAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *TorTargetsAPI) jsonCodec() JSONCodec {
func (api *simpleTorTargetsAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *TorTargetsAPI) httpClient() HTTPClient {
func (api *simpleTorTargetsAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -432,7 +432,7 @@ func (api *TorTargetsAPI) httpClient() HTTPClient {
}
// Call calls the TorTargets API.
func (api *TorTargetsAPI) Call(ctx context.Context, req *apimodel.TorTargetsRequest) (apimodel.TorTargetsResponse, error) {
func (api *simpleTorTargetsAPI) Call(ctx context.Context, req *apimodel.TorTargetsRequest) (apimodel.TorTargetsResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -448,8 +448,8 @@ func (api *TorTargetsAPI) Call(ctx context.Context, req *apimodel.TorTargetsRequ
return api.newResponse(api.httpClient().Do(httpReq))
}
// URLsAPI implements the URLs API.
type URLsAPI struct {
// simpleURLsAPI implements the URLs API.
type simpleURLsAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -457,28 +457,28 @@ type URLsAPI struct {
UserAgent string // optional
}
func (api *URLsAPI) baseURL() string {
func (api *simpleURLsAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *URLsAPI) requestMaker() RequestMaker {
func (api *simpleURLsAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *URLsAPI) jsonCodec() JSONCodec {
func (api *simpleURLsAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *URLsAPI) httpClient() HTTPClient {
func (api *simpleURLsAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -486,7 +486,7 @@ func (api *URLsAPI) httpClient() HTTPClient {
}
// Call calls the URLs API.
func (api *URLsAPI) Call(ctx context.Context, req *apimodel.URLsRequest) (*apimodel.URLsResponse, error) {
func (api *simpleURLsAPI) Call(ctx context.Context, req *apimodel.URLsRequest) (*apimodel.URLsResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -498,8 +498,8 @@ func (api *URLsAPI) Call(ctx context.Context, req *apimodel.URLsRequest) (*apimo
return api.newResponse(api.httpClient().Do(httpReq))
}
// OpenReportAPI implements the OpenReport API.
type OpenReportAPI struct {
// simpleOpenReportAPI implements the OpenReport API.
type simpleOpenReportAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
@ -507,28 +507,28 @@ type OpenReportAPI struct {
UserAgent string // optional
}
func (api *OpenReportAPI) baseURL() string {
func (api *simpleOpenReportAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *OpenReportAPI) requestMaker() RequestMaker {
func (api *simpleOpenReportAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *OpenReportAPI) jsonCodec() JSONCodec {
func (api *simpleOpenReportAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *OpenReportAPI) httpClient() HTTPClient {
func (api *simpleOpenReportAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -536,7 +536,7 @@ func (api *OpenReportAPI) httpClient() HTTPClient {
}
// Call calls the OpenReport API.
func (api *OpenReportAPI) Call(ctx context.Context, req *apimodel.OpenReportRequest) (*apimodel.OpenReportResponse, error) {
func (api *simpleOpenReportAPI) Call(ctx context.Context, req *apimodel.OpenReportRequest) (*apimodel.OpenReportResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err
@ -548,45 +548,45 @@ func (api *OpenReportAPI) Call(ctx context.Context, req *apimodel.OpenReportRequ
return api.newResponse(api.httpClient().Do(httpReq))
}
// SubmitMeasurementAPI implements the SubmitMeasurement API.
type SubmitMeasurementAPI struct {
// simpleSubmitMeasurementAPI implements the SubmitMeasurement API.
type simpleSubmitMeasurementAPI struct {
BaseURL string // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
RequestMaker RequestMaker // optional
TemplateExecutor TemplateExecutor // optional
TemplateExecutor templateExecutor // optional
UserAgent string // optional
}
func (api *SubmitMeasurementAPI) baseURL() string {
func (api *simpleSubmitMeasurementAPI) baseURL() string {
if api.BaseURL != "" {
return api.BaseURL
}
return "https://ps1.ooni.io"
}
func (api *SubmitMeasurementAPI) requestMaker() RequestMaker {
func (api *simpleSubmitMeasurementAPI) requestMaker() RequestMaker {
if api.RequestMaker != nil {
return api.RequestMaker
}
return &defaultRequestMaker{}
}
func (api *SubmitMeasurementAPI) jsonCodec() JSONCodec {
func (api *simpleSubmitMeasurementAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *SubmitMeasurementAPI) templateExecutor() TemplateExecutor {
func (api *simpleSubmitMeasurementAPI) templateExecutor() templateExecutor {
if api.TemplateExecutor != nil {
return api.TemplateExecutor
}
return &defaultTemplateExecutor{}
}
func (api *SubmitMeasurementAPI) httpClient() HTTPClient {
func (api *simpleSubmitMeasurementAPI) httpClient() HTTPClient {
if api.HTTPClient != nil {
return api.HTTPClient
}
@ -594,7 +594,7 @@ func (api *SubmitMeasurementAPI) httpClient() HTTPClient {
}
// Call calls the SubmitMeasurement API.
func (api *SubmitMeasurementAPI) Call(ctx context.Context, req *apimodel.SubmitMeasurementRequest) (*apimodel.SubmitMeasurementResponse, error) {
func (api *simpleSubmitMeasurementAPI) Call(ctx context.Context, req *apimodel.SubmitMeasurementRequest) (*apimodel.SubmitMeasurementResponse, error) {
httpReq, err := api.newRequest(ctx, req)
if err != nil {
return nil, err

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:50.81792142 +0100 CET m=+0.000095792
// 2021-03-10 13:17:32.206416809 +0100 CET m=+0.000074280
package ooapi
@ -22,7 +22,7 @@ import (
)
func TestCheckReportIDInvalidURL(t *testing.T) {
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -41,7 +41,7 @@ func TestCheckReportIDInvalidURL(t *testing.T) {
func TestCheckReportIDWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -59,7 +59,7 @@ func TestCheckReportIDWithHTTPErr(t *testing.T) {
func TestCheckReportIDWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -77,7 +77,7 @@ func TestCheckReportIDWithNewRequestErr(t *testing.T) {
func TestCheckReportIDWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -95,7 +95,7 @@ func TestCheckReportIDWith401(t *testing.T) {
func TestCheckReportIDWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -117,7 +117,7 @@ func TestCheckReportIDWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -139,7 +139,7 @@ func TestCheckReportIDWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -209,7 +209,7 @@ func TestCheckReportIDRoundTrip(t *testing.T) {
req := &apimodel.CheckReportIDRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &CheckReportIDAPI{BaseURL: srvr.URL}
api := &simpleCheckReportIDAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -252,7 +252,7 @@ func TestCheckReportIDMandatoryFields(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{
StatusCode: 500,
}}
api := &CheckReportIDAPI{
api := &simpleCheckReportIDAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -267,7 +267,7 @@ func TestCheckReportIDMandatoryFields(t *testing.T) {
}
func TestCheckInInvalidURL(t *testing.T) {
api := &CheckInAPI{
api := &simpleCheckInAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -286,7 +286,7 @@ func TestCheckInInvalidURL(t *testing.T) {
func TestCheckInWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &CheckInAPI{
api := &simpleCheckInAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -304,7 +304,7 @@ func TestCheckInWithHTTPErr(t *testing.T) {
func TestCheckInMarshalErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &CheckInAPI{
api := &simpleCheckInAPI{
JSONCodec: &FakeCodec{EncodeErr: errMocked},
}
ctx := context.Background()
@ -322,7 +322,7 @@ func TestCheckInMarshalErr(t *testing.T) {
func TestCheckInWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &CheckInAPI{
api := &simpleCheckInAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -340,7 +340,7 @@ func TestCheckInWithNewRequestErr(t *testing.T) {
func TestCheckInWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &CheckInAPI{
api := &simpleCheckInAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -358,7 +358,7 @@ func TestCheckInWith401(t *testing.T) {
func TestCheckInWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &CheckInAPI{
api := &simpleCheckInAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -380,7 +380,7 @@ func TestCheckInWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &CheckInAPI{
api := &simpleCheckInAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -402,7 +402,7 @@ func TestCheckInWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &CheckInAPI{
api := &simpleCheckInAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -472,7 +472,7 @@ func TestCheckInRoundTrip(t *testing.T) {
req := &apimodel.CheckInRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &CheckInAPI{BaseURL: srvr.URL}
api := &simpleCheckInAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -512,7 +512,7 @@ func TestCheckInRoundTrip(t *testing.T) {
}
func TestLoginInvalidURL(t *testing.T) {
api := &LoginAPI{
api := &simpleLoginAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -531,7 +531,7 @@ func TestLoginInvalidURL(t *testing.T) {
func TestLoginWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &LoginAPI{
api := &simpleLoginAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -549,7 +549,7 @@ func TestLoginWithHTTPErr(t *testing.T) {
func TestLoginMarshalErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &LoginAPI{
api := &simpleLoginAPI{
JSONCodec: &FakeCodec{EncodeErr: errMocked},
}
ctx := context.Background()
@ -567,7 +567,7 @@ func TestLoginMarshalErr(t *testing.T) {
func TestLoginWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &LoginAPI{
api := &simpleLoginAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -585,7 +585,7 @@ func TestLoginWithNewRequestErr(t *testing.T) {
func TestLoginWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &LoginAPI{
api := &simpleLoginAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -603,7 +603,7 @@ func TestLoginWith401(t *testing.T) {
func TestLoginWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &LoginAPI{
api := &simpleLoginAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -625,7 +625,7 @@ func TestLoginWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &LoginAPI{
api := &simpleLoginAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -647,7 +647,7 @@ func TestLoginWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &LoginAPI{
api := &simpleLoginAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -717,7 +717,7 @@ func TestLoginRoundTrip(t *testing.T) {
req := &apimodel.LoginRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &LoginAPI{BaseURL: srvr.URL}
api := &simpleLoginAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -757,7 +757,7 @@ func TestLoginRoundTrip(t *testing.T) {
}
func TestMeasurementMetaInvalidURL(t *testing.T) {
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -776,7 +776,7 @@ func TestMeasurementMetaInvalidURL(t *testing.T) {
func TestMeasurementMetaWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -794,7 +794,7 @@ func TestMeasurementMetaWithHTTPErr(t *testing.T) {
func TestMeasurementMetaWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -812,7 +812,7 @@ func TestMeasurementMetaWithNewRequestErr(t *testing.T) {
func TestMeasurementMetaWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -830,7 +830,7 @@ func TestMeasurementMetaWith401(t *testing.T) {
func TestMeasurementMetaWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -852,7 +852,7 @@ func TestMeasurementMetaWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -874,7 +874,7 @@ func TestMeasurementMetaWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -944,7 +944,7 @@ func TestMeasurementMetaRoundTrip(t *testing.T) {
req := &apimodel.MeasurementMetaRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &MeasurementMetaAPI{BaseURL: srvr.URL}
api := &simpleMeasurementMetaAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -987,7 +987,7 @@ func TestMeasurementMetaMandatoryFields(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{
StatusCode: 500,
}}
api := &MeasurementMetaAPI{
api := &simpleMeasurementMetaAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1002,7 +1002,7 @@ func TestMeasurementMetaMandatoryFields(t *testing.T) {
}
func TestRegisterInvalidURL(t *testing.T) {
api := &RegisterAPI{
api := &simpleRegisterAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -1021,7 +1021,7 @@ func TestRegisterInvalidURL(t *testing.T) {
func TestRegisterWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &RegisterAPI{
api := &simpleRegisterAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1039,7 +1039,7 @@ func TestRegisterWithHTTPErr(t *testing.T) {
func TestRegisterMarshalErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &RegisterAPI{
api := &simpleRegisterAPI{
JSONCodec: &FakeCodec{EncodeErr: errMocked},
}
ctx := context.Background()
@ -1057,7 +1057,7 @@ func TestRegisterMarshalErr(t *testing.T) {
func TestRegisterWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &RegisterAPI{
api := &simpleRegisterAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -1075,7 +1075,7 @@ func TestRegisterWithNewRequestErr(t *testing.T) {
func TestRegisterWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &RegisterAPI{
api := &simpleRegisterAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1093,7 +1093,7 @@ func TestRegisterWith401(t *testing.T) {
func TestRegisterWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &RegisterAPI{
api := &simpleRegisterAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1115,7 +1115,7 @@ func TestRegisterWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &RegisterAPI{
api := &simpleRegisterAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1137,7 +1137,7 @@ func TestRegisterWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &RegisterAPI{
api := &simpleRegisterAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -1207,7 +1207,7 @@ func TestRegisterRoundTrip(t *testing.T) {
req := &apimodel.RegisterRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &RegisterAPI{BaseURL: srvr.URL}
api := &simpleRegisterAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -1247,7 +1247,7 @@ func TestRegisterRoundTrip(t *testing.T) {
}
func TestTestHelpersInvalidURL(t *testing.T) {
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -1266,7 +1266,7 @@ func TestTestHelpersInvalidURL(t *testing.T) {
func TestTestHelpersWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1284,7 +1284,7 @@ func TestTestHelpersWithHTTPErr(t *testing.T) {
func TestTestHelpersWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -1302,7 +1302,7 @@ func TestTestHelpersWithNewRequestErr(t *testing.T) {
func TestTestHelpersWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1320,7 +1320,7 @@ func TestTestHelpersWith401(t *testing.T) {
func TestTestHelpersWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1342,7 +1342,7 @@ func TestTestHelpersWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1364,7 +1364,7 @@ func TestTestHelpersWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -1434,7 +1434,7 @@ func TestTestHelpersRoundTrip(t *testing.T) {
req := &apimodel.TestHelpersRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &TestHelpersAPI{BaseURL: srvr.URL}
api := &simpleTestHelpersAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -1478,7 +1478,7 @@ func TestTestHelpersResponseLiteralNull(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`null`)},
}}
api := &TestHelpersAPI{
api := &simpleTestHelpersAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -1495,7 +1495,7 @@ func TestTestHelpersResponseLiteralNull(t *testing.T) {
}
func TestPsiphonConfigInvalidURL(t *testing.T) {
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -1512,7 +1512,7 @@ func TestPsiphonConfigInvalidURL(t *testing.T) {
}
func TestPsiphonConfigWithMissingToken(t *testing.T) {
api := &PsiphonConfigAPI{} // no token
api := &simplePsiphonConfigAPI{} // no token
ctx := context.Background()
req := &apimodel.PsiphonConfigRequest{}
ff := &fakeFill{}
@ -1529,7 +1529,7 @@ func TestPsiphonConfigWithMissingToken(t *testing.T) {
func TestPsiphonConfigWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1548,7 +1548,7 @@ func TestPsiphonConfigWithHTTPErr(t *testing.T) {
func TestPsiphonConfigWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
Token: "fakeToken",
}
@ -1567,7 +1567,7 @@ func TestPsiphonConfigWithNewRequestErr(t *testing.T) {
func TestPsiphonConfigWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1586,7 +1586,7 @@ func TestPsiphonConfigWith401(t *testing.T) {
func TestPsiphonConfigWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1609,7 +1609,7 @@ func TestPsiphonConfigWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1632,7 +1632,7 @@ func TestPsiphonConfigWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
Token: "fakeToken",
@ -1703,7 +1703,7 @@ func TestPsiphonConfigRoundTrip(t *testing.T) {
req := &apimodel.PsiphonConfigRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &PsiphonConfigAPI{BaseURL: srvr.URL}
api := &simplePsiphonConfigAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
ff.fill(&api.Token)
// issue request
@ -1748,7 +1748,7 @@ func TestPsiphonConfigResponseLiteralNull(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`null`)},
}}
api := &PsiphonConfigAPI{
api := &simplePsiphonConfigAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1766,7 +1766,7 @@ func TestPsiphonConfigResponseLiteralNull(t *testing.T) {
}
func TestTorTargetsInvalidURL(t *testing.T) {
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -1783,7 +1783,7 @@ func TestTorTargetsInvalidURL(t *testing.T) {
}
func TestTorTargetsWithMissingToken(t *testing.T) {
api := &TorTargetsAPI{} // no token
api := &simpleTorTargetsAPI{} // no token
ctx := context.Background()
req := &apimodel.TorTargetsRequest{}
ff := &fakeFill{}
@ -1800,7 +1800,7 @@ func TestTorTargetsWithMissingToken(t *testing.T) {
func TestTorTargetsWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1819,7 +1819,7 @@ func TestTorTargetsWithHTTPErr(t *testing.T) {
func TestTorTargetsWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
Token: "fakeToken",
}
@ -1838,7 +1838,7 @@ func TestTorTargetsWithNewRequestErr(t *testing.T) {
func TestTorTargetsWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1857,7 +1857,7 @@ func TestTorTargetsWith401(t *testing.T) {
func TestTorTargetsWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1880,7 +1880,7 @@ func TestTorTargetsWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -1903,7 +1903,7 @@ func TestTorTargetsWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
Token: "fakeToken",
@ -1974,7 +1974,7 @@ func TestTorTargetsRoundTrip(t *testing.T) {
req := &apimodel.TorTargetsRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &TorTargetsAPI{BaseURL: srvr.URL}
api := &simpleTorTargetsAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
ff.fill(&api.Token)
// issue request
@ -2019,7 +2019,7 @@ func TestTorTargetsResponseLiteralNull(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`null`)},
}}
api := &TorTargetsAPI{
api := &simpleTorTargetsAPI{
HTTPClient: clnt,
Token: "fakeToken",
}
@ -2037,7 +2037,7 @@ func TestTorTargetsResponseLiteralNull(t *testing.T) {
}
func TestURLsInvalidURL(t *testing.T) {
api := &URLsAPI{
api := &simpleURLsAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -2056,7 +2056,7 @@ func TestURLsInvalidURL(t *testing.T) {
func TestURLsWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &URLsAPI{
api := &simpleURLsAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2074,7 +2074,7 @@ func TestURLsWithHTTPErr(t *testing.T) {
func TestURLsWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &URLsAPI{
api := &simpleURLsAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -2092,7 +2092,7 @@ func TestURLsWithNewRequestErr(t *testing.T) {
func TestURLsWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &URLsAPI{
api := &simpleURLsAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2110,7 +2110,7 @@ func TestURLsWith401(t *testing.T) {
func TestURLsWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &URLsAPI{
api := &simpleURLsAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2132,7 +2132,7 @@ func TestURLsWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &URLsAPI{
api := &simpleURLsAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2154,7 +2154,7 @@ func TestURLsWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &URLsAPI{
api := &simpleURLsAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -2224,7 +2224,7 @@ func TestURLsRoundTrip(t *testing.T) {
req := &apimodel.URLsRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &URLsAPI{BaseURL: srvr.URL}
api := &simpleURLsAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -2264,7 +2264,7 @@ func TestURLsRoundTrip(t *testing.T) {
}
func TestOpenReportInvalidURL(t *testing.T) {
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -2283,7 +2283,7 @@ func TestOpenReportInvalidURL(t *testing.T) {
func TestOpenReportWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2301,7 +2301,7 @@ func TestOpenReportWithHTTPErr(t *testing.T) {
func TestOpenReportMarshalErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
JSONCodec: &FakeCodec{EncodeErr: errMocked},
}
ctx := context.Background()
@ -2319,7 +2319,7 @@ func TestOpenReportMarshalErr(t *testing.T) {
func TestOpenReportWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -2337,7 +2337,7 @@ func TestOpenReportWithNewRequestErr(t *testing.T) {
func TestOpenReportWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2355,7 +2355,7 @@ func TestOpenReportWith401(t *testing.T) {
func TestOpenReportWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2377,7 +2377,7 @@ func TestOpenReportWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2399,7 +2399,7 @@ func TestOpenReportWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &OpenReportAPI{
api := &simpleOpenReportAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -2469,7 +2469,7 @@ func TestOpenReportRoundTrip(t *testing.T) {
req := &apimodel.OpenReportRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &OpenReportAPI{BaseURL: srvr.URL}
api := &simpleOpenReportAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -2509,7 +2509,7 @@ func TestOpenReportRoundTrip(t *testing.T) {
}
func TestSubmitMeasurementInvalidURL(t *testing.T) {
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
BaseURL: "\t", // invalid
}
ctx := context.Background()
@ -2528,7 +2528,7 @@ func TestSubmitMeasurementInvalidURL(t *testing.T) {
func TestSubmitMeasurementWithHTTPErr(t *testing.T) {
errMocked := errors.New("mocked error")
clnt := &FakeHTTPClient{Err: errMocked}
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2546,7 +2546,7 @@ func TestSubmitMeasurementWithHTTPErr(t *testing.T) {
func TestSubmitMeasurementMarshalErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
JSONCodec: &FakeCodec{EncodeErr: errMocked},
}
ctx := context.Background()
@ -2564,7 +2564,7 @@ func TestSubmitMeasurementMarshalErr(t *testing.T) {
func TestSubmitMeasurementWithNewRequestErr(t *testing.T) {
errMocked := errors.New("mocked error")
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
RequestMaker: &FakeRequestMaker{Err: errMocked},
}
ctx := context.Background()
@ -2582,7 +2582,7 @@ func TestSubmitMeasurementWithNewRequestErr(t *testing.T) {
func TestSubmitMeasurementWith401(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 401}}
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2600,7 +2600,7 @@ func TestSubmitMeasurementWith401(t *testing.T) {
func TestSubmitMeasurementWith400(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{StatusCode: 400}}
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2622,7 +2622,7 @@ func TestSubmitMeasurementWithResponseBodyReadErr(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Err: errMocked},
}}
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
HTTPClient: clnt,
}
ctx := context.Background()
@ -2644,7 +2644,7 @@ func TestSubmitMeasurementWithUnmarshalFailure(t *testing.T) {
StatusCode: 200,
Body: &FakeBody{Data: []byte(`{}`)},
}}
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
HTTPClient: clnt,
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
@ -2714,7 +2714,7 @@ func TestSubmitMeasurementRoundTrip(t *testing.T) {
req := &apimodel.SubmitMeasurementRequest{}
ff := &fakeFill{}
ff.fill(&req)
api := &SubmitMeasurementAPI{BaseURL: srvr.URL}
api := &simpleSubmitMeasurementAPI{BaseURL: srvr.URL}
ff.fill(&api.UserAgent)
// issue request
ctx := context.Background()
@ -2758,7 +2758,7 @@ func TestSubmitMeasurementTemplateErr(t *testing.T) {
clnt := &FakeHTTPClient{Resp: &http.Response{
StatusCode: 500,
}}
api := &SubmitMeasurementAPI{
api := &simpleSubmitMeasurementAPI{
HTTPClient: clnt,
TemplateExecutor: &FakeTemplateExecutor{Err: errMocked},
}

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:51.194159684 +0100 CET m=+0.000175181
// 2021-03-10 13:17:32.455000394 +0100 CET m=+0.000119352
package ooapi
@ -12,20 +12,20 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
// MeasurementMetaCache implements caching for MeasurementMetaAPI.
type MeasurementMetaCache struct {
API MeasurementMetaCaller // mandatory
GobCodec GobCodec // optional
KVStore KVStore // mandatory
// withCacheMeasurementMetaAPI implements caching for simpleMeasurementMetaAPI.
type withCacheMeasurementMetaAPI struct {
API callerForMeasurementMetaAPI // mandatory
GobCodec GobCodec // optional
KVStore KVStore // mandatory
}
type cacheEntryForMeasurementMeta struct {
type cacheEntryForMeasurementMetaAPI struct {
Req *apimodel.MeasurementMetaRequest
Resp *apimodel.MeasurementMetaResponse
}
// Call calls the API and implements caching.
func (c *MeasurementMetaCache) Call(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error) {
func (c *withCacheMeasurementMetaAPI) Call(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error) {
if resp, _ := c.readcache(req); resp != nil {
return resp, nil
}
@ -39,26 +39,26 @@ func (c *MeasurementMetaCache) Call(ctx context.Context, req *apimodel.Measureme
return resp, nil
}
func (c *MeasurementMetaCache) gobCodec() GobCodec {
func (c *withCacheMeasurementMetaAPI) gobCodec() GobCodec {
if c.GobCodec != nil {
return c.GobCodec
}
return &defaultGobCodec{}
}
func (c *MeasurementMetaCache) getcache() ([]cacheEntryForMeasurementMeta, error) {
func (c *withCacheMeasurementMetaAPI) getcache() ([]cacheEntryForMeasurementMetaAPI, error) {
data, err := c.KVStore.Get("MeasurementMeta.cache")
if err != nil {
return nil, err
}
var out []cacheEntryForMeasurementMeta
var out []cacheEntryForMeasurementMetaAPI
if err := c.gobCodec().Decode(data, &out); err != nil {
return nil, err
}
return out, nil
}
func (c *MeasurementMetaCache) setcache(in []cacheEntryForMeasurementMeta) error {
func (c *withCacheMeasurementMetaAPI) setcache(in []cacheEntryForMeasurementMetaAPI) error {
data, err := c.gobCodec().Encode(in)
if err != nil {
return err
@ -66,7 +66,7 @@ func (c *MeasurementMetaCache) setcache(in []cacheEntryForMeasurementMeta) error
return c.KVStore.Set("MeasurementMeta.cache", data)
}
func (c *MeasurementMetaCache) readcache(req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error) {
func (c *withCacheMeasurementMetaAPI) readcache(req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error) {
cache, err := c.getcache()
if err != nil {
return nil, err
@ -79,9 +79,9 @@ func (c *MeasurementMetaCache) readcache(req *apimodel.MeasurementMetaRequest) (
return nil, errCacheNotFound
}
func (c *MeasurementMetaCache) writecache(req *apimodel.MeasurementMetaRequest, resp *apimodel.MeasurementMetaResponse) error {
func (c *withCacheMeasurementMetaAPI) writecache(req *apimodel.MeasurementMetaRequest, resp *apimodel.MeasurementMetaResponse) error {
cache, _ := c.getcache()
out := []cacheEntryForMeasurementMeta{{Req: req, Resp: resp}}
out := []cacheEntryForMeasurementMetaAPI{{Req: req, Resp: resp}}
const toomany = 64
for idx, cur := range cache {
if reflect.DeepEqual(req, cur.Req) {
@ -95,4 +95,4 @@ func (c *MeasurementMetaCache) writecache(req *apimodel.MeasurementMetaRequest,
return c.setcache(out)
}
var _ MeasurementMetaCaller = &MeasurementMetaCache{}
var _ callerForMeasurementMetaAPI = &withCacheMeasurementMetaAPI{}

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:51.49660021 +0100 CET m=+0.000217672
// 2021-03-10 13:17:32.727159555 +0100 CET m=+0.000080664
package ooapi
@ -14,15 +14,15 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
func TestCacheMeasurementMetaAPISuccess(t *testing.T) {
func TestCachesimpleMeasurementMetaAPISuccess(t *testing.T) {
ff := &fakeFill{}
var expect *apimodel.MeasurementMetaResponse
ff.fill(&expect)
cache := &MeasurementMetaCache{
cache := &withCacheMeasurementMetaAPI{
API: &FakeMeasurementMetaAPI{
Response: expect,
},
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.MeasurementMetaRequest
ff.fill(&req)
@ -39,12 +39,12 @@ func TestCacheMeasurementMetaAPISuccess(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPIWriteCacheError(t *testing.T) {
func TestCachesimpleMeasurementMetaAPIWriteCacheError(t *testing.T) {
errMocked := errors.New("mocked error")
ff := &fakeFill{}
var expect *apimodel.MeasurementMetaResponse
ff.fill(&expect)
cache := &MeasurementMetaCache{
cache := &withCacheMeasurementMetaAPI{
API: &FakeMeasurementMetaAPI{
Response: expect,
},
@ -62,14 +62,14 @@ func TestCacheMeasurementMetaAPIWriteCacheError(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPIFailureWithNoCache(t *testing.T) {
func TestCachesimpleMeasurementMetaAPIFailureWithNoCache(t *testing.T) {
errMocked := errors.New("mocked error")
ff := &fakeFill{}
cache := &MeasurementMetaCache{
cache := &withCacheMeasurementMetaAPI{
API: &FakeMeasurementMetaAPI{
Err: errMocked,
},
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.MeasurementMetaRequest
ff.fill(&req)
@ -83,16 +83,16 @@ func TestCacheMeasurementMetaAPIFailureWithNoCache(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPIFailureWithPreviousCache(t *testing.T) {
func TestCachesimpleMeasurementMetaAPIFailureWithPreviousCache(t *testing.T) {
ff := &fakeFill{}
var expect *apimodel.MeasurementMetaResponse
ff.fill(&expect)
fakeapi := &FakeMeasurementMetaAPI{
Response: expect,
}
cache := &MeasurementMetaCache{
cache := &withCacheMeasurementMetaAPI{
API: fakeapi,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.MeasurementMetaRequest
ff.fill(&req)
@ -127,12 +127,12 @@ func TestCacheMeasurementMetaAPIFailureWithPreviousCache(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPISetcacheWithEncodeError(t *testing.T) {
func TestCachesimpleMeasurementMetaAPISetcacheWithEncodeError(t *testing.T) {
ff := &fakeFill{}
errMocked := errors.New("mocked error")
var in []cacheEntryForMeasurementMeta
var in []cacheEntryForMeasurementMetaAPI
ff.fill(&in)
cache := &MeasurementMetaCache{
cache := &withCacheMeasurementMetaAPI{
GobCodec: &FakeCodec{EncodeErr: errMocked},
}
err := cache.setcache(in)
@ -141,12 +141,12 @@ func TestCacheMeasurementMetaAPISetcacheWithEncodeError(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPIReadCacheNotFound(t *testing.T) {
func TestCachesimpleMeasurementMetaAPIReadCacheNotFound(t *testing.T) {
ff := &fakeFill{}
var incache []cacheEntryForMeasurementMeta
var incache []cacheEntryForMeasurementMetaAPI
ff.fill(&incache)
cache := &MeasurementMetaCache{
KVStore: &memkvstore{},
cache := &withCacheMeasurementMetaAPI{
KVStore: &MemKVStore{},
}
err := cache.setcache(incache)
if err != nil {
@ -163,7 +163,7 @@ func TestCacheMeasurementMetaAPIReadCacheNotFound(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPIWriteCacheDuplicate(t *testing.T) {
func TestCachesimpleMeasurementMetaAPIWriteCacheDuplicate(t *testing.T) {
ff := &fakeFill{}
var req *apimodel.MeasurementMetaRequest
ff.fill(&req)
@ -171,8 +171,8 @@ func TestCacheMeasurementMetaAPIWriteCacheDuplicate(t *testing.T) {
ff.fill(&resp1)
var resp2 *apimodel.MeasurementMetaResponse
ff.fill(&resp2)
cache := &MeasurementMetaCache{
KVStore: &memkvstore{},
cache := &withCacheMeasurementMetaAPI{
KVStore: &MemKVStore{},
}
err := cache.writecache(req, resp1)
if err != nil {
@ -194,10 +194,10 @@ func TestCacheMeasurementMetaAPIWriteCacheDuplicate(t *testing.T) {
}
}
func TestCacheMeasurementMetaAPICacheSizeLimited(t *testing.T) {
func TestCachesimpleMeasurementMetaAPICacheSizeLimited(t *testing.T) {
ff := &fakeFill{}
cache := &MeasurementMetaCache{
KVStore: &memkvstore{},
cache := &withCacheMeasurementMetaAPI{
KVStore: &MemKVStore{},
}
var prev int
for {

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:51.773813223 +0100 CET m=+0.000114768
// 2021-03-10 13:17:32.990745473 +0100 CET m=+0.000093232
package ooapi
@ -11,68 +11,68 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
// CheckReportIDCaller represents any type exposing a method
// like CheckReportIDAPI.Call.
type CheckReportIDCaller interface {
// callerForCheckReportIDAPI represents any type exposing a method
// like simpleCheckReportIDAPI.Call.
type callerForCheckReportIDAPI interface {
Call(ctx context.Context, req *apimodel.CheckReportIDRequest) (*apimodel.CheckReportIDResponse, error)
}
// CheckInCaller represents any type exposing a method
// like CheckInAPI.Call.
type CheckInCaller interface {
// callerForCheckInAPI represents any type exposing a method
// like simpleCheckInAPI.Call.
type callerForCheckInAPI interface {
Call(ctx context.Context, req *apimodel.CheckInRequest) (*apimodel.CheckInResponse, error)
}
// LoginCaller represents any type exposing a method
// like LoginAPI.Call.
type LoginCaller interface {
// callerForLoginAPI represents any type exposing a method
// like simpleLoginAPI.Call.
type callerForLoginAPI interface {
Call(ctx context.Context, req *apimodel.LoginRequest) (*apimodel.LoginResponse, error)
}
// MeasurementMetaCaller represents any type exposing a method
// like MeasurementMetaAPI.Call.
type MeasurementMetaCaller interface {
// callerForMeasurementMetaAPI represents any type exposing a method
// like simpleMeasurementMetaAPI.Call.
type callerForMeasurementMetaAPI interface {
Call(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*apimodel.MeasurementMetaResponse, error)
}
// RegisterCaller represents any type exposing a method
// like RegisterAPI.Call.
type RegisterCaller interface {
// callerForRegisterAPI represents any type exposing a method
// like simpleRegisterAPI.Call.
type callerForRegisterAPI interface {
Call(ctx context.Context, req *apimodel.RegisterRequest) (*apimodel.RegisterResponse, error)
}
// TestHelpersCaller represents any type exposing a method
// like TestHelpersAPI.Call.
type TestHelpersCaller interface {
// callerForTestHelpersAPI represents any type exposing a method
// like simpleTestHelpersAPI.Call.
type callerForTestHelpersAPI interface {
Call(ctx context.Context, req *apimodel.TestHelpersRequest) (apimodel.TestHelpersResponse, error)
}
// PsiphonConfigCaller represents any type exposing a method
// like PsiphonConfigAPI.Call.
type PsiphonConfigCaller interface {
// callerForPsiphonConfigAPI represents any type exposing a method
// like simplePsiphonConfigAPI.Call.
type callerForPsiphonConfigAPI interface {
Call(ctx context.Context, req *apimodel.PsiphonConfigRequest) (apimodel.PsiphonConfigResponse, error)
}
// TorTargetsCaller represents any type exposing a method
// like TorTargetsAPI.Call.
type TorTargetsCaller interface {
// callerForTorTargetsAPI represents any type exposing a method
// like simpleTorTargetsAPI.Call.
type callerForTorTargetsAPI interface {
Call(ctx context.Context, req *apimodel.TorTargetsRequest) (apimodel.TorTargetsResponse, error)
}
// URLsCaller represents any type exposing a method
// like URLsAPI.Call.
type URLsCaller interface {
// callerForURLsAPI represents any type exposing a method
// like simpleURLsAPI.Call.
type callerForURLsAPI interface {
Call(ctx context.Context, req *apimodel.URLsRequest) (*apimodel.URLsResponse, error)
}
// OpenReportCaller represents any type exposing a method
// like OpenReportAPI.Call.
type OpenReportCaller interface {
// callerForOpenReportAPI represents any type exposing a method
// like simpleOpenReportAPI.Call.
type callerForOpenReportAPI interface {
Call(ctx context.Context, req *apimodel.OpenReportRequest) (*apimodel.OpenReportResponse, error)
}
// SubmitMeasurementCaller represents any type exposing a method
// like SubmitMeasurementAPI.Call.
type SubmitMeasurementCaller interface {
// callerForSubmitMeasurementAPI represents any type exposing a method
// like simpleSubmitMeasurementAPI.Call.
type callerForSubmitMeasurementAPI interface {
Call(ctx context.Context, req *apimodel.SubmitMeasurementRequest) (*apimodel.SubmitMeasurementResponse, error)
}

View File

@ -0,0 +1,13 @@
package ooapi
// Client is a client for speaking with the OONI API. Make sure you
// fill in the mandatory fields.
type Client struct {
BaseURL string // optional
GobCodec GobCodec // optional
HTTPClient HTTPClient // optional
JSONCodec JSONCodec // optional
KVStore KVStore // mandatory
RequestMaker RequestMaker // optional
UserAgent string // optional
}

View File

@ -0,0 +1,214 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-03-10 13:17:33.307415377 +0100 CET m=+0.000150212
package ooapi
//go:generate go run ./internal/generator -file clientcall.go
import (
"context"
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
func (c *Client) newCheckReportIDCaller() callerForCheckReportIDAPI {
return &simpleCheckReportIDAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
}
}
// CheckReportID calls the CheckReportID API.
func (c *Client) CheckReportID(
ctx context.Context, req *apimodel.CheckReportIDRequest,
) (*apimodel.CheckReportIDResponse, error) {
api := c.newCheckReportIDCaller()
return api.Call(ctx, req)
}
func (c *Client) newCheckInCaller() callerForCheckInAPI {
return &simpleCheckInAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
}
}
// CheckIn calls the CheckIn API.
func (c *Client) CheckIn(
ctx context.Context, req *apimodel.CheckInRequest,
) (*apimodel.CheckInResponse, error) {
api := c.newCheckInCaller()
return api.Call(ctx, req)
}
func (c *Client) newMeasurementMetaCaller() callerForMeasurementMetaAPI {
return &withCacheMeasurementMetaAPI{
API: &simpleMeasurementMetaAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
GobCodec: c.GobCodec,
KVStore: c.KVStore,
}
}
// MeasurementMeta calls the MeasurementMeta API.
func (c *Client) MeasurementMeta(
ctx context.Context, req *apimodel.MeasurementMetaRequest,
) (*apimodel.MeasurementMetaResponse, error) {
api := c.newMeasurementMetaCaller()
return api.Call(ctx, req)
}
func (c *Client) newTestHelpersCaller() callerForTestHelpersAPI {
return &simpleTestHelpersAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
}
}
// TestHelpers calls the TestHelpers API.
func (c *Client) TestHelpers(
ctx context.Context, req *apimodel.TestHelpersRequest,
) (apimodel.TestHelpersResponse, error) {
api := c.newTestHelpersCaller()
return api.Call(ctx, req)
}
func (c *Client) newPsiphonConfigCaller() callerForPsiphonConfigAPI {
return &withLoginPsiphonConfigAPI{
API: &simplePsiphonConfigAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
JSONCodec: c.JSONCodec,
KVStore: c.KVStore,
RegisterAPI: &simpleRegisterAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
LoginAPI: &simpleLoginAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
}
}
// PsiphonConfig calls the PsiphonConfig API.
func (c *Client) PsiphonConfig(
ctx context.Context, req *apimodel.PsiphonConfigRequest,
) (apimodel.PsiphonConfigResponse, error) {
api := c.newPsiphonConfigCaller()
return api.Call(ctx, req)
}
func (c *Client) newTorTargetsCaller() callerForTorTargetsAPI {
return &withLoginTorTargetsAPI{
API: &simpleTorTargetsAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
JSONCodec: c.JSONCodec,
KVStore: c.KVStore,
RegisterAPI: &simpleRegisterAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
LoginAPI: &simpleLoginAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
},
}
}
// TorTargets calls the TorTargets API.
func (c *Client) TorTargets(
ctx context.Context, req *apimodel.TorTargetsRequest,
) (apimodel.TorTargetsResponse, error) {
api := c.newTorTargetsCaller()
return api.Call(ctx, req)
}
func (c *Client) newURLsCaller() callerForURLsAPI {
return &simpleURLsAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
}
}
// URLs calls the URLs API.
func (c *Client) URLs(
ctx context.Context, req *apimodel.URLsRequest,
) (*apimodel.URLsResponse, error) {
api := c.newURLsCaller()
return api.Call(ctx, req)
}
func (c *Client) newOpenReportCaller() callerForOpenReportAPI {
return &simpleOpenReportAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
}
}
// OpenReport calls the OpenReport API.
func (c *Client) OpenReport(
ctx context.Context, req *apimodel.OpenReportRequest,
) (*apimodel.OpenReportResponse, error) {
api := c.newOpenReportCaller()
return api.Call(ctx, req)
}
func (c *Client) newSubmitMeasurementCaller() callerForSubmitMeasurementAPI {
return &simpleSubmitMeasurementAPI{
BaseURL: c.BaseURL,
HTTPClient: c.HTTPClient,
JSONCodec: c.JSONCodec,
RequestMaker: c.RequestMaker,
UserAgent: c.UserAgent,
}
}
// SubmitMeasurement calls the SubmitMeasurement API.
func (c *Client) SubmitMeasurement(
ctx context.Context, req *apimodel.SubmitMeasurementRequest,
) (*apimodel.SubmitMeasurementResponse, error) {
api := c.newSubmitMeasurementCaller()
return api.Call(ctx, req)
}

View File

@ -0,0 +1,898 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-03-10 13:17:33.590560357 +0100 CET m=+0.000145982
package ooapi
//go:generate go run ./internal/generator -file clientcall_test.go
import (
"context"
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"sync"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
type handleClientCallCheckReportID struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp *apimodel.CheckReportIDResponse
url *url.URL
userAgent string
}
func (h *handleClientCallCheckReportID) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out *apimodel.CheckReportIDResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestCheckReportIDClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallCheckReportID{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.CheckReportIDRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.CheckReportID(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "GET" {
t.Fatal("invalid method")
}
// check the query
api := &simpleCheckReportIDAPI{BaseURL: srvr.URL}
httpReq, err := api.newRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != "" {
t.Fatal(diff)
}
if diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallCheckIn struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp *apimodel.CheckInResponse
url *url.URL
userAgent string
}
func (h *handleClientCallCheckIn) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out *apimodel.CheckInResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestCheckInClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallCheckIn{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.CheckInRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.CheckIn(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "POST" {
t.Fatal("invalid method")
}
// check the body
if handler.contentType != "application/json" {
t.Fatal("invalid content-type header")
}
got := &apimodel.CheckInRequest{}
if err := json.Unmarshal(handler.body, &got); err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(req, got); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallMeasurementMeta struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp *apimodel.MeasurementMetaResponse
url *url.URL
userAgent string
}
func (h *handleClientCallMeasurementMeta) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out *apimodel.MeasurementMetaResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestMeasurementMetaClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallMeasurementMeta{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.MeasurementMetaRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.MeasurementMeta(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "GET" {
t.Fatal("invalid method")
}
// check the query
api := &simpleMeasurementMetaAPI{BaseURL: srvr.URL}
httpReq, err := api.newRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != "" {
t.Fatal(diff)
}
if diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallTestHelpers struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp apimodel.TestHelpersResponse
url *url.URL
userAgent string
}
func (h *handleClientCallTestHelpers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out apimodel.TestHelpersResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestTestHelpersClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallTestHelpers{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.TestHelpersRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.TestHelpers(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "GET" {
t.Fatal("invalid method")
}
// check the query
api := &simpleTestHelpersAPI{BaseURL: srvr.URL}
httpReq, err := api.newRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != "" {
t.Fatal(diff)
}
if diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallPsiphonConfig struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp apimodel.PsiphonConfigResponse
url *url.URL
userAgent string
}
func (h *handleClientCallPsiphonConfig) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
if r.URL.Path == "/api/v1/register" {
var out apimodel.RegisterResponse
ff.fill(&out)
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
return
}
if r.URL.Path == "/api/v1/login" {
var out apimodel.LoginResponse
ff.fill(&out)
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
return
}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out apimodel.PsiphonConfigResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestPsiphonConfigClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallPsiphonConfig{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.PsiphonConfigRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.PsiphonConfig(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "GET" {
t.Fatal("invalid method")
}
// check the query
api := &simplePsiphonConfigAPI{BaseURL: srvr.URL}
httpReq, err := api.newRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != "" {
t.Fatal(diff)
}
if diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallTorTargets struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp apimodel.TorTargetsResponse
url *url.URL
userAgent string
}
func (h *handleClientCallTorTargets) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
if r.URL.Path == "/api/v1/register" {
var out apimodel.RegisterResponse
ff.fill(&out)
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
return
}
if r.URL.Path == "/api/v1/login" {
var out apimodel.LoginResponse
ff.fill(&out)
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
return
}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out apimodel.TorTargetsResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestTorTargetsClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallTorTargets{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.TorTargetsRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.TorTargets(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "GET" {
t.Fatal("invalid method")
}
// check the query
api := &simpleTorTargetsAPI{BaseURL: srvr.URL}
httpReq, err := api.newRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != "" {
t.Fatal(diff)
}
if diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallURLs struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp *apimodel.URLsResponse
url *url.URL
userAgent string
}
func (h *handleClientCallURLs) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out *apimodel.URLsResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestURLsClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallURLs{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.URLsRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.URLs(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "GET" {
t.Fatal("invalid method")
}
// check the query
api := &simpleURLsAPI{BaseURL: srvr.URL}
httpReq, err := api.newRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != "" {
t.Fatal(diff)
}
if diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallOpenReport struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp *apimodel.OpenReportResponse
url *url.URL
userAgent string
}
func (h *handleClientCallOpenReport) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out *apimodel.OpenReportResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestOpenReportClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallOpenReport{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.OpenReportRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.OpenReport(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "POST" {
t.Fatal("invalid method")
}
// check the body
if handler.contentType != "application/json" {
t.Fatal("invalid content-type header")
}
got := &apimodel.OpenReportRequest{}
if err := json.Unmarshal(handler.body, &got); err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(req, got); diff != "" {
t.Fatal(diff)
}
}
type handleClientCallSubmitMeasurement struct {
accept string
body []byte
contentType string
count int32
method string
mu sync.Mutex
resp *apimodel.SubmitMeasurementResponse
url *url.URL
userAgent string
}
func (h *handleClientCallSubmitMeasurement) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ff := fakeFill{}
defer h.mu.Unlock()
h.mu.Lock()
if h.count > 0 {
w.WriteHeader(400)
return
}
h.count++
if r.Body != nil {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(400)
return
}
h.body = data
}
h.method = r.Method
h.url = r.URL
h.accept = r.Header.Get("Accept")
h.contentType = r.Header.Get("Content-Type")
h.userAgent = r.Header.Get("User-Agent")
var out *apimodel.SubmitMeasurementResponse
ff.fill(&out)
h.resp = out
data, err := json.Marshal(out)
if err != nil {
w.WriteHeader(400)
return
}
w.Write(data)
}
func TestSubmitMeasurementClientCallRoundTrip(t *testing.T) {
// setup
handler := &handleClientCallSubmitMeasurement{}
srvr := httptest.NewServer(handler)
defer srvr.Close()
req := &apimodel.SubmitMeasurementRequest{}
ff := &fakeFill{}
ff.fill(&req)
clnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}
ff.fill(&clnt.UserAgent)
// issue request
ctx := context.Background()
resp, err := clnt.SubmitMeasurement(ctx, req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response here")
}
// compare our response and server's one
if diff := cmp.Diff(handler.resp, resp); diff != "" {
t.Fatal(diff)
}
// check whether headers are OK
if handler.accept != "application/json" {
t.Fatal("invalid accept header")
}
if handler.userAgent != clnt.UserAgent {
t.Fatal("invalid user-agent header")
}
// check whether the method is OK
if handler.method != "POST" {
t.Fatal("invalid method")
}
// check the body
if handler.contentType != "application/json" {
t.Fatal("invalid content-type header")
}
got := &apimodel.SubmitMeasurementRequest{}
if err := json.Unmarshal(handler.body, &got); err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(req, got); diff != "" {
t.Fatal(diff)
}
}

View File

@ -1,18 +1,18 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:52.108352268 +0100 CET m=+0.000275862
// 2021-03-10 13:17:33.849313529 +0100 CET m=+0.000136772
package ooapi
//go:generate go run ./internal/generator -file cloners.go
// PsiphonConfigCaller represents any type exposing a method
// like PsiphonConfigAPI.WithToken.
type PsiphonConfigCloner interface {
WithToken(token string) PsiphonConfigCaller
// clonerForPsiphonConfigAPI represents any type exposing a method
// like simplePsiphonConfigAPI.WithToken.
type clonerForPsiphonConfigAPI interface {
WithToken(token string) callerForPsiphonConfigAPI
}
// TorTargetsCaller represents any type exposing a method
// like TorTargetsAPI.WithToken.
type TorTargetsCloner interface {
WithToken(token string) TorTargetsCaller
// clonerForTorTargetsAPI represents any type exposing a method
// like simpleTorTargetsAPI.WithToken.
type clonerForTorTargetsAPI interface {
WithToken(token string) callerForTorTargetsAPI
}

View File

@ -21,8 +21,8 @@ type RequestMaker interface {
NewRequest(ctx context.Context, method, URL string, body io.Reader) (*http.Request, error)
}
// TemplateExecutor parses and executes a text template.
type TemplateExecutor interface {
// templateExecutor parses and executes a text template.
type templateExecutor interface {
// Execute takes in input a template string and some piece of data. It
// returns either a string where template parameters have been replaced,
// on success, or an error, on failure.

View File

@ -1,108 +1,19 @@
// Package ooapi contains clients for the OONI API. We
// automatically generate the code in this package from
// the apimodel and internal/generator packages. For
// each OONI API, we define up to three data structures:
// Package ooapi contains a client for the OONI API. We
// automatically generate the code in this package from the
// apimodel and internal/generator packages.
//
// 1. a data structure representing the API;
// Usage
//
// 2. a caching data structure, if the API
// supports caching;
// You need to create a Client. Make sure you set all
// the mandatory fields. You will then have a function
// for every supported OONI API. This function will
// take in input a context and a request. You need to
// fill the request, of course. The return value is
// either a response or an error.
//
// 3. an auto-login data structure, if the API
// requires login.
//
// The rest of this documentation page describes these
// three data structures and the design and architecture
// of this package. Refer to subpackages for more
// information on how to specify an API.
//
// API data structure
//
// For each API, this package defines a data structure
// representing the API. For example, for the TorTargets API,
// we define the TorTargetsAPI data structure.
//
// The API data structure defines a method named Call that
// allows calling the specified API. Call takes as arguments
// a context and the request for the API and returns the
// API response or an error.
//
// Request and response messages live inside the apimodel
// subpackage. We name them after the API. Thus, for
// the TorTargets API, the request is TorTargetsRequest,
// and the response is TorTargetsResponse.
//
// API data structures are cheap to create and do not
// mutate. They should be used in place and then forgotten
// off once the API call is complete.
//
// Unless explicitly indicated, the zero value of every
// API data structure is a valid API data structure.
//
// In terms of dependencies, APIs certainly need an http.Client
// to communicate with the OONI backend. To represent such a
// client, we use the HTTPClient interface. If you do not tell
// an API which http.Client to use, we will default to the
// standard library's http.DefaultClient.
//
// An API also depends on a JSONCodec. That is, on a data
// structures that encodes data to/from JSON. If you do not
// specify explicitly a JSONCodec, we will use the Go
// standard library's JSON implementation.
//
// When an API requires authentication, you need to tell
// it which authentication token to use. This gives you
// control over obtaining the token and is the low-level
// way of interacting with authenticated APIs. We recommend
// using the auto-login wrappers instead (see below).
//
// Authenticated APIs also define the WithToken method. This
// method takes as argument a token and returns a copy of the
// original API using the given token. We use this method
// to implement auto-login wrappers.
//
// For each API, we also define two interfaces:
//
// 1. the Caller interface represents the possibility of
// calling a specific API with the correct arguments;
//
// 2. the Cloner interface represents the possibility of
// calling WithToken on the given API.
//
// They abstract the interaction between the API type and
// its caching and auto-login wrappers.
//
// Caching
//
// If an API supports caching, we define a type whose name
// ends in Cache. The TorTargets API cache, for example,
// is TorTargetsCache. These caching types wrap the API type
// and provide the caching functionality.
//
// Because the cache needs to read from and write to the
// disk, a caching type needs a KVStore. A KVStore is
// an interface that allow you to bind a specific key to
// a given blob of bytes and to retrieve such bytes later.
//
// Caches use the gob data format from the Go standard
// library (`encoding/gob`). We abstract this dependency
// using the GobCodec interface. By default, when you
// do not specify a GobCodec we use the implementation
// of gob from the Go standard library.
//
// See the example describing caching for more information
// on how to use caching.
//
// Auto-login
//
// If an API supports auto-login, we define a type whose
// name ends with WithLogin. The TorTargets auto-login struct,
// for example, is called TorTargetsAPIWithLogin.
//
// Auto-login wrappers need to store persistent data. We
// use a KVStore for that (see above). We encode login data
// using JSON. To this end, we use a JSONCodec (also
// described above).
// If an API requires login, we will automatically
// perform the login. If an API uses caching, we will
// automatically use the cache.
//
// See the example describing auto-login for more information
// on how to use auto-login.
@ -142,22 +53,4 @@
// The ./internal/generator contains code to generate most
// code in this package. In particular, the spec.go file is
// the specification of the APIs.
//
// Notable generated files
//
// - apis.go: contains APIs (e.g., TorTargetsAPI);
//
// - caching.go: contains caching wrappers for every API
// that declares that it needs a cache (e.g., TorTargetsCache);
//
// - callers.go: contains Callers;
//
// - cloners.go: contains the Cloners;
//
// - login.go: contains auto-login wrappers (e.g.,
// TorTargetsAPIWithLogin);
//
// - requests.go: contains code to generate http.Requests.
//
// - responses.go: code to parse http.Responses.
package ooapi

View File

@ -2,13 +2,13 @@ package ooapi
import "errors"
// Errors defined by this package. In addition to these errors, this
// package may of course return any other stdlib specific error.
// Errors defined by this package.
var (
ErrEmptyField = errors.New("apiclient: empty field")
ErrHTTPFailure = errors.New("apiclient: http request failed")
ErrJSONLiteralNull = errors.New("apiclient: server returned us a literal null")
ErrMissingToken = errors.New("apiclient: missing auth token")
ErrUnauthorized = errors.New("apiclient: not authorized")
errCacheNotFound = errors.New("apiclient: not found in cache")
ErrAPICallFailed = errors.New("ooapi: API call failed")
ErrEmptyField = errors.New("ooapi: empty field")
ErrHTTPFailure = errors.New("ooapi: http request failed")
ErrJSONLiteralNull = errors.New("ooapi: server returned us a literal null")
ErrMissingToken = errors.New("ooapi: missing auth token")
ErrUnauthorized = errors.New("ooapi: not authorized")
errCacheNotFound = errors.New("ooapi: not found in cache")
)

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:52.357709034 +0100 CET m=+0.000208565
// 2021-03-10 13:17:34.086220417 +0100 CET m=+0.000080714
package ooapi
@ -24,7 +24,7 @@ func (fapi *FakeCheckReportIDAPI) Call(ctx context.Context, req *apimodel.CheckR
}
var (
_ CheckReportIDCaller = &FakeCheckReportIDAPI{}
_ callerForCheckReportIDAPI = &FakeCheckReportIDAPI{}
)
type FakeCheckInAPI struct {
@ -39,7 +39,7 @@ func (fapi *FakeCheckInAPI) Call(ctx context.Context, req *apimodel.CheckInReque
}
var (
_ CheckInCaller = &FakeCheckInAPI{}
_ callerForCheckInAPI = &FakeCheckInAPI{}
)
type FakeLoginAPI struct {
@ -54,7 +54,7 @@ func (fapi *FakeLoginAPI) Call(ctx context.Context, req *apimodel.LoginRequest)
}
var (
_ LoginCaller = &FakeLoginAPI{}
_ callerForLoginAPI = &FakeLoginAPI{}
)
type FakeMeasurementMetaAPI struct {
@ -69,7 +69,7 @@ func (fapi *FakeMeasurementMetaAPI) Call(ctx context.Context, req *apimodel.Meas
}
var (
_ MeasurementMetaCaller = &FakeMeasurementMetaAPI{}
_ callerForMeasurementMetaAPI = &FakeMeasurementMetaAPI{}
)
type FakeRegisterAPI struct {
@ -84,7 +84,7 @@ func (fapi *FakeRegisterAPI) Call(ctx context.Context, req *apimodel.RegisterReq
}
var (
_ RegisterCaller = &FakeRegisterAPI{}
_ callerForRegisterAPI = &FakeRegisterAPI{}
)
type FakeTestHelpersAPI struct {
@ -99,11 +99,11 @@ func (fapi *FakeTestHelpersAPI) Call(ctx context.Context, req *apimodel.TestHelp
}
var (
_ TestHelpersCaller = &FakeTestHelpersAPI{}
_ callerForTestHelpersAPI = &FakeTestHelpersAPI{}
)
type FakePsiphonConfigAPI struct {
WithResult PsiphonConfigCaller
WithResult callerForPsiphonConfigAPI
Err error
Response apimodel.PsiphonConfigResponse
CountCall int32
@ -114,17 +114,17 @@ func (fapi *FakePsiphonConfigAPI) Call(ctx context.Context, req *apimodel.Psipho
return fapi.Response, fapi.Err
}
func (fapi *FakePsiphonConfigAPI) WithToken(token string) PsiphonConfigCaller {
func (fapi *FakePsiphonConfigAPI) WithToken(token string) callerForPsiphonConfigAPI {
return fapi.WithResult
}
var (
_ PsiphonConfigCaller = &FakePsiphonConfigAPI{}
_ PsiphonConfigCloner = &FakePsiphonConfigAPI{}
_ callerForPsiphonConfigAPI = &FakePsiphonConfigAPI{}
_ clonerForPsiphonConfigAPI = &FakePsiphonConfigAPI{}
)
type FakeTorTargetsAPI struct {
WithResult TorTargetsCaller
WithResult callerForTorTargetsAPI
Err error
Response apimodel.TorTargetsResponse
CountCall int32
@ -135,13 +135,13 @@ func (fapi *FakeTorTargetsAPI) Call(ctx context.Context, req *apimodel.TorTarget
return fapi.Response, fapi.Err
}
func (fapi *FakeTorTargetsAPI) WithToken(token string) TorTargetsCaller {
func (fapi *FakeTorTargetsAPI) WithToken(token string) callerForTorTargetsAPI {
return fapi.WithResult
}
var (
_ TorTargetsCaller = &FakeTorTargetsAPI{}
_ TorTargetsCloner = &FakeTorTargetsAPI{}
_ callerForTorTargetsAPI = &FakeTorTargetsAPI{}
_ clonerForTorTargetsAPI = &FakeTorTargetsAPI{}
)
type FakeURLsAPI struct {
@ -156,7 +156,7 @@ func (fapi *FakeURLsAPI) Call(ctx context.Context, req *apimodel.URLsRequest) (*
}
var (
_ URLsCaller = &FakeURLsAPI{}
_ callerForURLsAPI = &FakeURLsAPI{}
)
type FakeOpenReportAPI struct {
@ -171,7 +171,7 @@ func (fapi *FakeOpenReportAPI) Call(ctx context.Context, req *apimodel.OpenRepor
}
var (
_ OpenReportCaller = &FakeOpenReportAPI{}
_ callerForOpenReportAPI = &FakeOpenReportAPI{}
)
type FakeSubmitMeasurementAPI struct {
@ -186,5 +186,5 @@ func (fapi *FakeSubmitMeasurementAPI) Call(ctx context.Context, req *apimodel.Su
}
var (
_ SubmitMeasurementCaller = &FakeSubmitMeasurementAPI{}
_ callerForSubmitMeasurementAPI = &FakeSubmitMeasurementAPI{}
)

View File

@ -0,0 +1,21 @@
package ooapi
import (
"net/http"
"testing"
)
type VerboseHTTPClient struct {
T *testing.T
}
func (c *VerboseHTTPClient) Do(req *http.Request) (*http.Response, error) {
c.T.Logf("> %s %s", req.Method, req.URL.String())
resp, err := http.DefaultClient.Do(req)
if err != nil {
c.T.Logf("< %s", err.Error())
return nil, err
}
c.T.Logf("< %d", resp.StatusCode)
return resp, nil
}

View File

@ -1,28 +1,13 @@
package ooapi
package ooapi_test
import (
"context"
"net/http"
"testing"
"github.com/ooni/probe-cli/v3/internal/engine/ooapi"
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
type VerboseHTTPClient struct {
t *testing.T
}
func (c *VerboseHTTPClient) Do(req *http.Request) (*http.Response, error) {
c.t.Logf("> %s %s", req.Method, req.URL.String())
resp, err := http.DefaultClient.Do(req)
if err != nil {
c.t.Logf("< %s", err.Error())
return nil, err
}
c.t.Logf("< %d", resp.StatusCode)
return resp, nil
}
func TestWithRealServerDoCheckIn(t *testing.T) {
if testing.Short() {
t.Skip("skip test in short mode")
@ -40,12 +25,10 @@ func TestWithRealServerDoCheckIn(t *testing.T) {
CategoryCodes: []string{"NEWS", "CULTR"},
},
}
httpClnt := &VerboseHTTPClient{t: t}
api := &CheckInAPI{
HTTPClient: httpClnt,
}
httpClnt := &ooapi.VerboseHTTPClient{T: t}
clnt := &ooapi.Client{HTTPClient: httpClnt, KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.CheckIn(ctx, req)
if err != nil {
t.Fatal(err)
}
@ -67,9 +50,9 @@ func TestWithRealServerDoCheckReportID(t *testing.T) {
req := &apimodel.CheckReportIDRequest{
ReportID: "20210223T093606Z_ndt_JO_8376_n1_kDYToqrugDY54Soy",
}
api := &CheckReportIDAPI{}
clnt := &ooapi.Client{KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.CheckReportID(ctx, req)
if err != nil {
t.Fatal(err)
}
@ -86,9 +69,9 @@ func TestWithRealServerDoMeasurementMeta(t *testing.T) {
req := &apimodel.MeasurementMetaRequest{
ReportID: "20210223T093606Z_ndt_JO_8376_n1_kDYToqrugDY54Soy",
}
api := &MeasurementMetaAPI{}
clnt := &ooapi.Client{KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.MeasurementMeta(ctx, req)
if err != nil {
t.Fatal(err)
}
@ -113,9 +96,9 @@ func TestWithRealServerDoOpenReport(t *testing.T) {
TestStartTime: "2018-11-01 15:33:20",
TestVersion: "0.1.0",
}
api := &OpenReportAPI{}
clnt := &ooapi.Client{KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.OpenReport(ctx, req)
if err != nil {
t.Fatal(err)
}
@ -130,21 +113,10 @@ func TestWithRealServerDoPsiphonConfig(t *testing.T) {
t.Skip("skip test in short mode")
}
req := &apimodel.PsiphonConfigRequest{}
httpClnt := &VerboseHTTPClient{t: t}
api := &PsiphonConfigAPIWithLogin{
API: &PsiphonConfigAPI{
HTTPClient: httpClnt,
},
KVStore: &memkvstore{},
RegisterAPI: &RegisterAPI{
HTTPClient: httpClnt,
},
LoginAPI: &LoginAPI{
HTTPClient: httpClnt,
},
}
httpClnt := &ooapi.VerboseHTTPClient{T: t}
clnt := &ooapi.Client{HTTPClient: httpClnt, KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.PsiphonConfig(ctx, req)
if err != nil {
t.Fatal(err)
}
@ -159,21 +131,10 @@ func TestWithRealServerDoTorTargets(t *testing.T) {
t.Skip("skip test in short mode")
}
req := &apimodel.TorTargetsRequest{}
httpClnt := &VerboseHTTPClient{t: t}
api := &TorTargetsAPIWithLogin{
API: &TorTargetsAPI{
HTTPClient: httpClnt,
},
KVStore: &memkvstore{},
RegisterAPI: &RegisterAPI{
HTTPClient: httpClnt,
},
LoginAPI: &LoginAPI{
HTTPClient: httpClnt,
},
}
httpClnt := &ooapi.VerboseHTTPClient{T: t}
clnt := &ooapi.Client{HTTPClient: httpClnt, KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.TorTargets(ctx, req)
if err != nil {
t.Fatal(err)
}
@ -191,9 +152,9 @@ func TestWithRealServerDoURLs(t *testing.T) {
CountryCode: "IT",
Limit: 3,
}
api := &URLsAPI{}
clnt := &ooapi.Client{KVStore: &ooapi.MemKVStore{}}
ctx := context.Background()
resp, err := api.Call(ctx, req)
resp, err := clnt.URLs(ctx, req)
if err != nil {
t.Fatal(err)
}

View File

@ -54,7 +54,7 @@ var apiFields = []apiField{{
comment: "optional",
}, {
name: "TemplateExecutor",
kind: "TemplateExecutor",
kind: "templateExecutor",
comment: "optional",
ifTemplate: true,
}, {
@ -120,7 +120,7 @@ func (d *Descriptor) genNewAPI(sb *strings.Builder) {
if d.URLPath.IsTemplate {
fmt.Fprintf(
sb, "func (api *%s) templateExecutor() TemplateExecutor {\n",
sb, "func (api *%s) templateExecutor() templateExecutor {\n",
d.APIStructName())
fmt.Fprint(sb, "\tif api.TemplateExecutor != nil {\n")
fmt.Fprint(sb, "\t\treturn api.TemplateExecutor\n")

View File

@ -8,8 +8,8 @@ import (
func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprintf(sb, "// %s implements caching for %s.\n",
d.CacheStructName(), d.APIStructName())
fmt.Fprintf(sb, "type %s struct {\n", d.CacheStructName())
d.WithCacheAPIStructName(), d.APIStructName())
fmt.Fprintf(sb, "type %s struct {\n", d.WithCacheAPIStructName())
fmt.Fprintf(sb, "\tAPI %s // mandatory\n", d.CallerInterfaceName())
fmt.Fprint(sb, "\tGobCodec GobCodec // optional\n")
fmt.Fprint(sb, "\tKVStore KVStore // mandatory\n")
@ -22,7 +22,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprintf(sb, "// Call calls the API and implements caching.\n")
fmt.Fprintf(sb, "func (c *%s) Call(ctx context.Context, req %s) (%s, error) {\n",
d.CacheStructName(), d.RequestTypeName(), d.ResponseTypeName())
d.WithCacheAPIStructName(), d.RequestTypeName(), d.ResponseTypeName())
if d.CachePolicy == CacheAlways {
fmt.Fprint(sb, "\tif resp, _ := c.readcache(req); resp != nil {\n")
fmt.Fprint(sb, "\t\treturn resp, nil\n")
@ -43,7 +43,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprint(sb, "\treturn resp, nil\n")
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "func (c *%s) gobCodec() GobCodec {\n", d.CacheStructName())
fmt.Fprintf(sb, "func (c *%s) gobCodec() GobCodec {\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\tif c.GobCodec != nil {\n")
fmt.Fprint(sb, "\t\treturn c.GobCodec\n")
fmt.Fprint(sb, "\t}\n")
@ -51,7 +51,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "func (c *%s) getcache() ([]%s, error) {\n",
d.CacheStructName(), d.CacheEntryName())
d.WithCacheAPIStructName(), d.CacheEntryName())
fmt.Fprintf(sb, "\tdata, err := c.KVStore.Get(\"%s\")\n", d.CacheKey())
fmt.Fprint(sb, "\tif err != nil {\n")
fmt.Fprint(sb, "\t\treturn nil, err\n")
@ -64,7 +64,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "func (c *%s) setcache(in []%s) error {\n",
d.CacheStructName(), d.CacheEntryName())
d.WithCacheAPIStructName(), d.CacheEntryName())
fmt.Fprint(sb, "\tdata, err := c.gobCodec().Encode(in)\n")
fmt.Fprint(sb, "\tif err != nil {\n")
fmt.Fprint(sb, "\t\treturn err\n")
@ -73,7 +73,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "func (c *%s) readcache(req %s) (%s, error) {\n",
d.CacheStructName(), d.RequestTypeName(), d.ResponseTypeName())
d.WithCacheAPIStructName(), d.RequestTypeName(), d.ResponseTypeName())
fmt.Fprint(sb, "\tcache, err := c.getcache()\n")
fmt.Fprint(sb, "\tif err != nil {\n")
fmt.Fprint(sb, "\t\treturn nil, err\n")
@ -87,7 +87,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "func (c *%s) writecache(req %s, resp %s) error {\n",
d.CacheStructName(), d.RequestTypeName(), d.ResponseTypeName())
d.WithCacheAPIStructName(), d.RequestTypeName(), d.ResponseTypeName())
fmt.Fprint(sb, "\tcache, _ := c.getcache()\n")
fmt.Fprintf(sb, "\tout := []%s{{Req: req, Resp: resp}}\n", d.CacheEntryName())
fmt.Fprint(sb, "\tconst toomany = 64\n")
@ -104,7 +104,7 @@ func (d *Descriptor) genNewCache(sb *strings.Builder) {
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "var _ %s = &%s{}\n\n", d.CallerInterfaceName(),
d.CacheStructName())
d.WithCacheAPIStructName())
}
// GenCachingGo generates caching.go.

View File

@ -11,11 +11,11 @@ func (d *Descriptor) genTestCacheSuccess(sb *strings.Builder) {
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
fmt.Fprint(sb, "\tff.fill(&req)\n")
@ -39,8 +39,8 @@ func (d *Descriptor) genTestWriteCacheError(sb *strings.Builder) {
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tKVStore: &FakeKVStore{SetError: errMocked},\n")
@ -62,11 +62,11 @@ func (d *Descriptor) genTestFailureWithNoCache(sb *strings.Builder) {
fmt.Fprintf(sb, "func TestCache%sFailureWithNoCache(t *testing.T) {\n", d.APIStructName())
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\tErr: errMocked,\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
fmt.Fprint(sb, "\tff.fill(&req)\n")
@ -87,12 +87,12 @@ func (d *Descriptor) genTestFailureWithPreviousCache(sb *strings.Builder) {
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
fmt.Fprintf(sb, "\tfakeapi := &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\tfakeapi := &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\t\tAPI: fakeapi,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
fmt.Fprint(sb, "\tff.fill(&req)\n")
@ -134,7 +134,7 @@ func (d *Descriptor) genTestSetcacheWithEncodeError(sb *strings.Builder) {
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
fmt.Fprintf(sb, "\tvar in []%s\n", d.CacheEntryName())
fmt.Fprint(sb, "\tff.fill(&in)\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\t\tGobCodec: &FakeCodec{EncodeErr: errMocked},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\terr := cache.setcache(in)\n")
@ -155,8 +155,8 @@ func (d *Descriptor) genTestReadCacheNotFound(sb *strings.Builder) {
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar incache []%s\n", d.CacheEntryName())
fmt.Fprint(sb, "\tff.fill(&incache)\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\terr := cache.setcache(incache)\n")
fmt.Fprintf(sb, "\tif err != nil {\n")
@ -183,8 +183,8 @@ func (d *Descriptor) genTestWriteCacheDuplicate(sb *strings.Builder) {
fmt.Fprint(sb, "\tff.fill(&resp1)\n")
fmt.Fprintf(sb, "\tvar resp2 %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&resp2)\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\terr := cache.writecache(req, resp1)\n")
fmt.Fprintf(sb, "\tif err != nil {\n")
@ -216,8 +216,8 @@ func (d *Descriptor) genTestCachSizeLimited(sb *strings.Builder) {
}
fmt.Fprintf(sb, "func TestCache%sCacheSizeLimited(t *testing.T) {\n", d.APIStructName())
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.CacheStructName())
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprintf(sb, "\tcache := &%s{\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar prev int\n")
fmt.Fprintf(sb, "\tfor {\n")

View File

@ -0,0 +1,104 @@
package main
import (
"fmt"
"strings"
"time"
)
func (d *Descriptor) clientMakeAPIBase(sb *strings.Builder) {
fmt.Fprintf(sb, "&%s{\n", d.APIStructName())
for _, field := range apiFields {
if field.ifLogin || field.ifTemplate {
continue
}
fmt.Fprintf(sb, "\t%s: c.%s,\n", field.name, field.name)
}
fmt.Fprint(sb, "}")
}
func (d *Descriptor) clientMakeAPI(sb *strings.Builder) {
if d.RequiresLogin && d.CachePolicy != CacheNone {
panic("we don't support requiresLogin with caching")
}
if d.RequiresLogin {
fmt.Fprintf(sb, "&%s{\n", d.WithLoginAPIStructName())
fmt.Fprint(sb, "\tAPI:")
d.clientMakeAPIBase(sb)
fmt.Fprint(sb, ",\n")
fmt.Fprint(sb, "\tJSONCodec: c.JSONCodec,\n")
fmt.Fprint(sb, "\tKVStore: c.KVStore,\n")
fmt.Fprint(sb, "\tRegisterAPI: &simpleRegisterAPI{\n")
for _, field := range apiFields {
if field.ifLogin || field.ifTemplate {
continue
}
fmt.Fprintf(sb, "\t%s: c.%s,\n", field.name, field.name)
}
fmt.Fprint(sb, "\t},\n")
fmt.Fprint(sb, "\tLoginAPI: &simpleLoginAPI{\n")
for _, field := range apiFields {
if field.ifLogin || field.ifTemplate {
continue
}
fmt.Fprintf(sb, "\t%s: c.%s,\n", field.name, field.name)
}
fmt.Fprint(sb, "\t},\n")
fmt.Fprint(sb, "}\n")
return
}
if d.CachePolicy != CacheNone {
fmt.Fprintf(sb, "&%s{\n", d.WithCacheAPIStructName())
fmt.Fprint(sb, "\tAPI:")
d.clientMakeAPIBase(sb)
fmt.Fprint(sb, ",\n")
fmt.Fprint(sb, "\tGobCodec: c.GobCodec,\n")
fmt.Fprint(sb, "\tKVStore: c.KVStore,\n")
fmt.Fprint(sb, "}\n")
return
}
d.clientMakeAPIBase(sb)
fmt.Fprint(sb, "\n")
}
func (d *Descriptor) genClientNewCaller(sb *strings.Builder) {
fmt.Fprintf(sb, "func (c *Client) new%sCaller() ", d.Name)
fmt.Fprintf(sb, "%s {\n", d.CallerInterfaceName())
fmt.Fprint(sb, "\treturn ")
d.clientMakeAPI(sb)
fmt.Fprint(sb, "}\n\n")
}
func (d *Descriptor) genClientCall(sb *strings.Builder) {
fmt.Fprintf(sb, "// %s calls the %s API.\n", d.Name, d.Name)
fmt.Fprintf(sb, "func (c *Client) %s(\n", d.Name)
fmt.Fprintf(sb, "ctx context.Context, req %s,\n) ", d.RequestTypeName())
fmt.Fprintf(sb, "(%s, error) {\n", d.ResponseTypeName())
fmt.Fprintf(sb, "\tapi := c.new%sCaller()\n", d.Name)
fmt.Fprint(sb, "\treturn api.Call(ctx, req)\n")
fmt.Fprint(sb, "}\n\n")
}
// GenClientCallGo generates clientcall.go.
func GenClientCallGo(file string) {
var sb strings.Builder
fmt.Fprint(&sb, "// Code generated by go generate; DO NOT EDIT.\n")
fmt.Fprintf(&sb, "// %s\n\n", time.Now())
fmt.Fprint(&sb, "package ooapi\n\n")
fmt.Fprintf(&sb, "//go:generate go run ./internal/generator -file %s\n\n", file)
fmt.Fprint(&sb, "import (\n")
fmt.Fprint(&sb, "\t\"context\"\n")
fmt.Fprint(&sb, "\n")
fmt.Fprint(&sb, "\t\"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel\"\n")
fmt.Fprint(&sb, ")\n")
for _, desc := range Descriptors {
switch desc.Name {
case "Register", "Login":
// We don't want to generate these APIs as toplevel.
continue
}
desc.genClientNewCaller(&sb)
desc.genClientCall(&sb)
}
writefile(file, &sb)
}

View File

@ -0,0 +1,181 @@
package main
import (
"fmt"
"strings"
"time"
)
func (d *Descriptor) genTestClientCallRoundTrip(sb *strings.Builder) {
// generate the type of the handler
fmt.Fprintf(sb, "type handleClientCall%s struct {\n", d.Name)
fmt.Fprint(sb, "\taccept string\n")
fmt.Fprint(sb, "\tbody []byte\n")
fmt.Fprint(sb, "\tcontentType string\n")
fmt.Fprint(sb, "\tcount int32\n")
fmt.Fprint(sb, "\tmethod string\n")
fmt.Fprint(sb, "\tmu sync.Mutex\n")
fmt.Fprintf(sb, "\tresp %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\turl *url.URL\n")
fmt.Fprint(sb, "\tuserAgent string\n")
fmt.Fprint(sb, "}\n\n")
// generate the handling function
fmt.Fprintf(sb,
"func (h *handleClientCall%s) ServeHTTP(w http.ResponseWriter, r *http.Request) {",
d.Name)
fmt.Fprint(sb, "\tff := fakeFill{}\n")
if d.RequiresLogin {
fmt.Fprintf(sb, "\tif r.URL.Path == \"/api/v1/register\" {\n")
fmt.Fprintf(sb, "\t\tvar out apimodel.RegisterResponse\n")
fmt.Fprintf(sb, "\t\tff.fill(&out)\n")
fmt.Fprintf(sb, "\t\tdata, err := json.Marshal(out)\n")
fmt.Fprintf(sb, "\t\tif err != nil {\n")
fmt.Fprintf(sb, "\t\t\tw.WriteHeader(400)\n")
fmt.Fprintf(sb, "\t\t\treturn\n")
fmt.Fprintf(sb, "\t\t}\n")
fmt.Fprintf(sb, "\t\tw.Write(data)\n")
fmt.Fprintf(sb, "\t\treturn\n")
fmt.Fprintf(sb, "\t}\n")
fmt.Fprintf(sb, "\tif r.URL.Path == \"/api/v1/login\" {\n")
fmt.Fprintf(sb, "\t\tvar out apimodel.LoginResponse\n")
fmt.Fprintf(sb, "\t\tff.fill(&out)\n")
fmt.Fprintf(sb, "\t\tdata, err := json.Marshal(out)\n")
fmt.Fprintf(sb, "\t\tif err != nil {\n")
fmt.Fprintf(sb, "\t\t\tw.WriteHeader(400)\n")
fmt.Fprintf(sb, "\t\t\treturn\n")
fmt.Fprintf(sb, "\t\t}\n")
fmt.Fprintf(sb, "\t\tw.Write(data)\n")
fmt.Fprintf(sb, "\t\treturn\n")
fmt.Fprintf(sb, "\t}\n")
}
fmt.Fprint(sb, "\tdefer h.mu.Unlock()\n")
fmt.Fprint(sb, "\th.mu.Lock()\n")
fmt.Fprint(sb, "\tif h.count > 0 {\n")
fmt.Fprint(sb, "\t\tw.WriteHeader(400)\n")
fmt.Fprint(sb, "\t\treturn\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\th.count++\n")
fmt.Fprint(sb, "\tif r.Body != nil {\n")
fmt.Fprint(sb, "\t\tdata, err := ioutil.ReadAll(r.Body)\n")
fmt.Fprint(sb, "\t\tif err != nil {\n")
fmt.Fprintf(sb, "\t\t\tw.WriteHeader(400)\n")
fmt.Fprintf(sb, "\t\t\treturn\n")
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprint(sb, "\t\th.body = data\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\th.method = r.Method\n")
fmt.Fprint(sb, "\th.url = r.URL\n")
fmt.Fprint(sb, "\th.accept = r.Header.Get(\"Accept\")\n")
fmt.Fprint(sb, "\th.contentType = r.Header.Get(\"Content-Type\")\n")
fmt.Fprint(sb, "\th.userAgent = r.Header.Get(\"User-Agent\")\n")
fmt.Fprintf(sb, "\tvar out %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&out)\n")
fmt.Fprintf(sb, "\th.resp = out\n")
fmt.Fprintf(sb, "\tdata, err := json.Marshal(out)\n")
fmt.Fprintf(sb, "\tif err != nil {\n")
fmt.Fprintf(sb, "\t\tw.WriteHeader(400)\n")
fmt.Fprintf(sb, "\t\treturn\n")
fmt.Fprintf(sb, "\t}\n")
fmt.Fprintf(sb, "\tw.Write(data)\n")
fmt.Fprintf(sb, "\t}\n\n")
// generate the test itself
fmt.Fprintf(sb, "func Test%sClientCallRoundTrip(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\t// setup\n")
fmt.Fprintf(sb, "\thandler := &handleClientCall%s{}\n", d.Name)
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
fmt.Fprintf(sb, "\treq := &%s{}\n", d.RequestTypeNameAsStruct())
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprint(sb, "\tff.fill(&req)\n")
fmt.Fprint(sb, "\tclnt := &Client{KVStore: &MemKVStore{}, BaseURL: srvr.URL}\n")
fmt.Fprint(sb, "\tff.fill(&clnt.UserAgent)\n")
fmt.Fprint(sb, "\t// issue request\n")
fmt.Fprint(sb, "\tctx := context.Background()\n")
fmt.Fprintf(sb, "\tresp, err := clnt.%s(ctx, req)\n", d.Name)
fmt.Fprint(sb, "\tif err != nil {\n")
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\tif resp == nil {\n")
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response here\")\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t// compare our response and server's one\n")
fmt.Fprint(sb, "\tif diff := cmp.Diff(handler.resp, resp); diff != \"\" {")
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t// check whether headers are OK\n")
fmt.Fprint(sb, "\tif handler.accept != \"application/json\" {\n")
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid accept header\")\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\tif handler.userAgent != clnt.UserAgent {\n")
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid user-agent header\")\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t// check whether the method is OK\n")
fmt.Fprintf(sb, "\tif handler.method != \"%s\" {\n", d.Method)
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid method\")\n")
fmt.Fprint(sb, "\t}\n")
if d.Method == "POST" {
fmt.Fprint(sb, "\t// check the body\n")
fmt.Fprint(sb, "\tif handler.contentType != \"application/json\" {\n")
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid content-type header\")\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tgot := &%s{}\n", d.RequestTypeNameAsStruct())
fmt.Fprintf(sb, "\tif err := json.Unmarshal(handler.body, &got); err != nil {\n")
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\tif diff := cmp.Diff(req, got); diff != \"\" {\n")
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
fmt.Fprint(sb, "\t}\n")
} else {
fmt.Fprint(sb, "\t// check the query\n")
fmt.Fprintf(sb, "\tapi := &%s{BaseURL: srvr.URL}\n", d.APIStructName())
fmt.Fprint(sb, "\thttpReq, err := api.newRequest(context.Background(), req)\n")
fmt.Fprint(sb, "\tif err != nil {\n")
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\tif diff := cmp.Diff(handler.url.Path, httpReq.URL.Path); diff != \"\" {\n")
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\tif diff := cmp.Diff(handler.url.RawQuery, httpReq.URL.RawQuery); diff != \"\" {\n")
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
fmt.Fprint(sb, "\t}\n")
}
fmt.Fprint(sb, "}\n\n")
}
// GenClientCallTestGo generates clientcall_test.go.
func GenClientCallTestGo(file string) {
var sb strings.Builder
fmt.Fprint(&sb, "// Code generated by go generate; DO NOT EDIT.\n")
fmt.Fprintf(&sb, "// %s\n\n", time.Now())
fmt.Fprint(&sb, "package ooapi\n\n")
fmt.Fprintf(&sb, "//go:generate go run ./internal/generator -file %s\n\n", file)
fmt.Fprint(&sb, "import (\n")
fmt.Fprint(&sb, "\t\"context\"\n")
fmt.Fprint(&sb, "\t\"encoding/json\"\n")
fmt.Fprint(&sb, "\t\"io/ioutil\"\n")
fmt.Fprint(&sb, "\t\"net/http/httptest\"\n")
fmt.Fprint(&sb, "\t\"net/http\"\n")
fmt.Fprint(&sb, "\t\"net/url\"\n")
fmt.Fprint(&sb, "\t\"testing\"\n")
fmt.Fprint(&sb, "\t\"sync\"\n")
fmt.Fprint(&sb, "\n")
fmt.Fprint(&sb, "\t\"github.com/google/go-cmp/cmp\"\n")
fmt.Fprint(&sb, "\t\"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel\"\n")
fmt.Fprint(&sb, ")\n")
for _, desc := range Descriptors {
if desc.Name == "Login" || desc.Name == "Register" {
continue // they cannot be called directly
}
desc.genTestClientCallRoundTrip(&sb)
}
writefile(file, &sb)
}

View File

@ -8,7 +8,7 @@ import (
func (d *Descriptor) genNewCloner(sb *strings.Builder) {
fmt.Fprintf(sb, "// %s represents any type exposing a method\n",
d.CallerInterfaceName())
d.ClonerInterfaceName())
fmt.Fprintf(sb, "// like %s.WithToken.\n", d.APIStructName())
fmt.Fprintf(sb, "type %s interface {\n", d.ClonerInterfaceName())
fmt.Fprintf(sb, "\tWithToken(token string) %s\n", d.CallerInterfaceName())

View File

@ -7,7 +7,7 @@ import (
)
func (d *Descriptor) genNewFakeAPI(sb *strings.Builder) {
fmt.Fprintf(sb, "type Fake%s struct {\n", d.APIStructName())
fmt.Fprintf(sb, "type %s struct {\n", d.FakeAPIStructName())
if d.RequiresLogin {
fmt.Fprintf(sb, "\tWithResult %s\n", d.CallerInterfaceName())
}
@ -16,25 +16,25 @@ func (d *Descriptor) genNewFakeAPI(sb *strings.Builder) {
fmt.Fprint(sb, "\tCountCall int32\n")
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "func (fapi *Fake%s) Call(ctx context.Context, req %s) (%s, error) {\n",
d.APIStructName(), d.RequestTypeName(), d.ResponseTypeName())
fmt.Fprintf(sb, "func (fapi *%s) Call(ctx context.Context, req %s) (%s, error) {\n",
d.FakeAPIStructName(), d.RequestTypeName(), d.ResponseTypeName())
fmt.Fprint(sb, "\tatomic.AddInt32(&fapi.CountCall, 1)\n")
fmt.Fprint(sb, "\treturn fapi.Response, fapi.Err\n")
fmt.Fprint(sb, "}\n\n")
if d.RequiresLogin {
fmt.Fprintf(sb, "func (fapi *Fake%s) WithToken(token string) %s {\n",
d.APIStructName(), d.CallerInterfaceName())
fmt.Fprintf(sb, "func (fapi *%s) WithToken(token string) %s {\n",
d.FakeAPIStructName(), d.CallerInterfaceName())
fmt.Fprint(sb, "\treturn fapi.WithResult\n")
fmt.Fprint(sb, "}\n\n")
}
fmt.Fprint(sb, "var (\n")
fmt.Fprintf(sb, "\t_ %s = &Fake%s{}\n", d.CallerInterfaceName(),
d.APIStructName())
fmt.Fprintf(sb, "\t_ %s = &%s{}\n", d.CallerInterfaceName(),
d.FakeAPIStructName())
if d.RequiresLogin {
fmt.Fprintf(sb, "\t_ %s = &Fake%s{}\n", d.ClonerInterfaceName(),
d.APIStructName())
fmt.Fprintf(sb, "\t_ %s = &%s{}\n", d.ClonerInterfaceName(),
d.FakeAPIStructName())
}
fmt.Fprint(sb, ")\n\n")
}

View File

@ -47,6 +47,10 @@ func main() {
GenCachingTestGo(file)
case "login_test.go":
GenLoginTestGo(file)
case "clientcall.go":
GenClientCallGo(file)
case "clientcall_test.go":
GenClientCallTestGo(file)
default:
panic(fmt.Sprintf("don't know how to create this file: %s", file))
}

View File

@ -13,8 +13,8 @@ func (d *Descriptor) genNewLogin(sb *strings.Builder) {
fmt.Fprintf(sb, "\tAPI %s // mandatory\n", d.ClonerInterfaceName())
fmt.Fprint(sb, "\tJSONCodec JSONCodec // optional\n")
fmt.Fprint(sb, "\tKVStore KVStore // mandatory\n")
fmt.Fprint(sb, "\tRegisterAPI RegisterCaller // mandatory\n")
fmt.Fprint(sb, "\tLoginAPI LoginCaller // mandatory\n")
fmt.Fprint(sb, "\tRegisterAPI callerForRegisterAPI // mandatory\n")
fmt.Fprint(sb, "\tLoginAPI callerForLoginAPI // mandatory\n")
fmt.Fprint(sb, "}\n\n")
fmt.Fprintf(sb, "// Call logins, if needed, then calls the API.\n")

View File

@ -7,7 +7,7 @@ import (
)
func (d *Descriptor) genTestRegisterAndLoginSuccess(sb *strings.Builder) {
fmt.Fprintf(sb, "func TestRegisterAndLogin%sSuccess(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func TestRegisterAndLogin%sSuccess(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -26,14 +26,14 @@ func (d *Descriptor) genTestRegisterAndLoginSuccess(sb *strings.Builder) {
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -62,7 +62,7 @@ func (d *Descriptor) genTestRegisterAndLoginSuccess(sb *strings.Builder) {
}
func (d *Descriptor) genTestContinueUsingToken(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sContinueUsingToken(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sContinueUsingToken(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -81,14 +81,14 @@ func (d *Descriptor) genTestContinueUsingToken(sb *strings.Builder) {
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -150,7 +150,7 @@ func (d *Descriptor) genTestContinueUsingToken(sb *strings.Builder) {
}
func (d *Descriptor) genTestWithValidButExpiredToken(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sWithValidButExpiredToken(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sWithValidButExpiredToken(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -168,14 +168,14 @@ func (d *Descriptor) genTestWithValidButExpiredToken(sb *strings.Builder) {
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tls := &loginState{\n")
@ -214,7 +214,7 @@ func (d *Descriptor) genTestWithValidButExpiredToken(sb *strings.Builder) {
}
func (d *Descriptor) genTestWithRegisterAPIError(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sWithRegisterAPIError(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sWithRegisterAPIError(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -225,13 +225,13 @@ func (d *Descriptor) genTestWithRegisterAPIError(sb *strings.Builder) {
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -253,7 +253,7 @@ func (d *Descriptor) genTestWithRegisterAPIError(sb *strings.Builder) {
}
func (d *Descriptor) genTestWithLoginFailure(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sWithLoginFailure(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sWithLoginFailure(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -270,14 +270,14 @@ func (d *Descriptor) genTestWithLoginFailure(sb *strings.Builder) {
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -303,7 +303,7 @@ func (d *Descriptor) genTestWithLoginFailure(sb *strings.Builder) {
}
func (d *Descriptor) genTestRegisterAndLoginThenFail(sb *strings.Builder) {
fmt.Fprintf(sb, "func TestRegisterAndLogin%sThenFail(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func TestRegisterAndLogin%sThenFail(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -323,14 +323,14 @@ func (d *Descriptor) genTestRegisterAndLoginThenFail(sb *strings.Builder) {
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tErr: errMocked,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -356,22 +356,22 @@ func (d *Descriptor) genTestRegisterAndLoginThenFail(sb *strings.Builder) {
}
func (d *Descriptor) genTestTheDatabaseIsReplaced(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sTheDatabaseIsReplaced(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sTheDatabaseIsReplaced(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprint(sb, "\thandler := &LoginHandler{t: t}\n")
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
fmt.Fprint(sb, "\tregisterAPI := &RegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t\tloginAPI := &LoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
@ -379,7 +379,7 @@ func (d *Descriptor) genTestTheDatabaseIsReplaced(sb *strings.Builder) {
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -430,22 +430,22 @@ func (d *Descriptor) genTestTheDatabaseIsReplaced(sb *strings.Builder) {
}
func (d *Descriptor) genTestTheDatabaseIsReplacedThenFailure(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sTheDatabaseIsReplacedThenFailure(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sTheDatabaseIsReplacedThenFailure(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprint(sb, "\thandler := &LoginHandler{t: t}\n")
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
fmt.Fprint(sb, "\tregisterAPI := &RegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t\tloginAPI := &LoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
@ -453,7 +453,7 @@ func (d *Descriptor) genTestTheDatabaseIsReplacedThenFailure(sb *strings.Builder
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -506,7 +506,7 @@ func (d *Descriptor) genTestTheDatabaseIsReplacedThenFailure(sb *strings.Builder
}
func (d *Descriptor) genTestRegisterAndLoginCannotWriteState(sb *strings.Builder) {
fmt.Fprintf(sb, "func TestRegisterAndLogin%sCannotWriteState(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func TestRegisterAndLogin%sCannotWriteState(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -526,14 +526,14 @@ func (d *Descriptor) genTestRegisterAndLoginCannotWriteState(sb *strings.Builder
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprintf(sb, "\t\tAPI: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &Fake%s{\n", d.APIStructName())
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
fmt.Fprint(sb, "\t\t\t},\n")
fmt.Fprint(sb, "\t\t},\n")
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t\tJSONCodec: &FakeCodec{\n")
fmt.Fprint(sb, "\t\t\tEncodeErr: errMocked,\n")
fmt.Fprint(sb, "\t\t},\n")
@ -562,7 +562,7 @@ func (d *Descriptor) genTestRegisterAndLoginCannotWriteState(sb *strings.Builder
}
func (d *Descriptor) genTestReadStateDecodeFailure(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sReadStateDecodeFailure(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sReadStateDecodeFailure(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
fmt.Fprint(sb, "\tff.fill(&expect)\n")
@ -570,7 +570,7 @@ func (d *Descriptor) genTestReadStateDecodeFailure(sb *strings.Builder) {
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
fmt.Fprint(sb, "\t\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\t\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t\tJSONCodec: &FakeCodec{DecodeErr: errMocked},\n")
fmt.Fprint(sb, "\t}\n")
@ -596,22 +596,22 @@ func (d *Descriptor) genTestReadStateDecodeFailure(sb *strings.Builder) {
}
func (d *Descriptor) genTestClockIsOffThenSuccess(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sClockIsOffThenSuccess(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sClockIsOffThenSuccess(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprint(sb, "\thandler := &LoginHandler{t: t}\n")
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
fmt.Fprint(sb, "\tregisterAPI := &RegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t\tloginAPI := &LoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
@ -619,7 +619,7 @@ func (d *Descriptor) genTestClockIsOffThenSuccess(sb *strings.Builder) {
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -672,22 +672,22 @@ func (d *Descriptor) genTestClockIsOffThenSuccess(sb *strings.Builder) {
}
func (d *Descriptor) genTestClockIsOffThen401(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sClockIsOffThen401(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sClockIsOffThen401(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprint(sb, "\thandler := &LoginHandler{t: t}\n")
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
fmt.Fprint(sb, "\tregisterAPI := &RegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t\tloginAPI := &LoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
@ -695,7 +695,7 @@ func (d *Descriptor) genTestClockIsOffThen401(sb *strings.Builder) {
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
@ -749,22 +749,22 @@ func (d *Descriptor) genTestClockIsOffThen401(sb *strings.Builder) {
}
func (d *Descriptor) genTestClockIsOffThen500(sb *strings.Builder) {
fmt.Fprintf(sb, "func Test%sClockIsOffThen500(t *testing.T) {\n", d.APIStructName())
fmt.Fprintf(sb, "func Test%sClockIsOffThen500(t *testing.T) {\n", d.Name)
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
fmt.Fprint(sb, "\thandler := &LoginHandler{t: t}\n")
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
fmt.Fprint(sb, "\tregisterAPI := &RegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprint(sb, "\t\tloginAPI := &LoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t\t}\n")
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{t: t},\n")
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
fmt.Fprint(sb, "\t}\n")
@ -772,7 +772,7 @@ func (d *Descriptor) genTestClockIsOffThen500(sb *strings.Builder) {
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
fmt.Fprint(sb, "\tKVStore: &memkvstore{},\n")
fmt.Fprint(sb, "\tKVStore: &MemKVStore{},\n")
fmt.Fprint(sb, "\t}\n")
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())

View File

@ -23,37 +23,43 @@ func (d *Descriptor) ResponseTypeName() string {
// APIStructName returns the correct struct type name
// for the API we're currently processing.
func (d *Descriptor) APIStructName() string {
return fmt.Sprintf("%sAPI", d.Name)
return fmt.Sprintf("simple%sAPI", d.Name)
}
// FakeAPIStructName returns the correct struct type name
// for the fake for the API we're currently processing.
func (d *Descriptor) FakeAPIStructName() string {
return fmt.Sprintf("Fake%sAPI", d.Name)
}
// WithLoginAPIStructName returns the correct struct type name
// for the WithLoginAPI we're currently processing.
func (d *Descriptor) WithLoginAPIStructName() string {
return fmt.Sprintf("%sAPIWithLogin", d.Name)
return fmt.Sprintf("withLogin%sAPI", d.Name)
}
// CallerInterfaceName returns the correct caller interface name
// for the API we're currently processing.
func (d *Descriptor) CallerInterfaceName() string {
return fmt.Sprintf("%sCaller", d.Name)
return fmt.Sprintf("callerFor%sAPI", d.Name)
}
// ClonerInterfaceName returns the correct cloner interface name
// for the API we're currently processing.
func (d *Descriptor) ClonerInterfaceName() string {
return fmt.Sprintf("%sCloner", d.Name)
return fmt.Sprintf("clonerFor%sAPI", d.Name)
}
// CacheStructName returns the correct struct type name for
// WithCacheAPIStructName returns the correct struct type name for
// the cache for the API we're currently processing.
func (d *Descriptor) CacheStructName() string {
return fmt.Sprintf("%sCache", d.Name)
func (d *Descriptor) WithCacheAPIStructName() string {
return fmt.Sprintf("withCache%sAPI", d.Name)
}
// CacheEntryName returns the correct struct type name for the
// cache entry for the API we're currently processing.
func (d *Descriptor) CacheEntryName() string {
return fmt.Sprintf("cacheEntryFor%s", d.Name)
return fmt.Sprintf("cacheEntryFor%sAPI", d.Name)
}
// CacheKey returns the correct cache key for the API

View File

@ -8,12 +8,12 @@ import (
var errMemkvstoreNotFound = errors.New("memkvstore: not found")
type memkvstore struct {
type MemKVStore struct {
m map[string][]byte
mu sync.Mutex
}
func (kvs *memkvstore) Get(key string) ([]byte, error) {
func (kvs *MemKVStore) Get(key string) ([]byte, error) {
defer kvs.mu.Unlock()
kvs.mu.Lock()
out, good := kvs.m[key]
@ -23,7 +23,7 @@ func (kvs *memkvstore) Get(key string) ([]byte, error) {
return out, nil
}
func (kvs *memkvstore) Set(key string, value []byte) error {
func (kvs *MemKVStore) Set(key string, value []byte) error {
defer kvs.mu.Unlock()
kvs.mu.Lock()
if kvs.m == nil {

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:52.62521737 +0100 CET m=+0.000161706
// 2021-03-10 13:17:34.342751918 +0100 CET m=+0.000196026
package ooapi
@ -12,17 +12,17 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
// PsiphonConfigAPIWithLogin implements login for PsiphonConfigAPI.
type PsiphonConfigAPIWithLogin struct {
API PsiphonConfigCloner // mandatory
JSONCodec JSONCodec // optional
KVStore KVStore // mandatory
RegisterAPI RegisterCaller // mandatory
LoginAPI LoginCaller // mandatory
// withLoginPsiphonConfigAPI implements login for simplePsiphonConfigAPI.
type withLoginPsiphonConfigAPI struct {
API clonerForPsiphonConfigAPI // mandatory
JSONCodec JSONCodec // optional
KVStore KVStore // mandatory
RegisterAPI callerForRegisterAPI // mandatory
LoginAPI callerForLoginAPI // mandatory
}
// Call logins, if needed, then calls the API.
func (api *PsiphonConfigAPIWithLogin) Call(ctx context.Context, req *apimodel.PsiphonConfigRequest) (apimodel.PsiphonConfigResponse, error) {
func (api *withLoginPsiphonConfigAPI) Call(ctx context.Context, req *apimodel.PsiphonConfigRequest) (apimodel.PsiphonConfigResponse, error) {
token, err := api.maybeLogin(ctx)
if err != nil {
return nil, err
@ -56,14 +56,14 @@ func (api *PsiphonConfigAPIWithLogin) Call(ctx context.Context, req *apimodel.Ps
return resp, nil
}
func (api *PsiphonConfigAPIWithLogin) jsonCodec() JSONCodec {
func (api *withLoginPsiphonConfigAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *PsiphonConfigAPIWithLogin) readstate() (*loginState, error) {
func (api *withLoginPsiphonConfigAPI) readstate() (*loginState, error) {
data, err := api.KVStore.Get(loginKey)
if err != nil {
return nil, err
@ -75,7 +75,7 @@ func (api *PsiphonConfigAPIWithLogin) readstate() (*loginState, error) {
return &ls, nil
}
func (api *PsiphonConfigAPIWithLogin) writestate(ls *loginState) error {
func (api *withLoginPsiphonConfigAPI) writestate(ls *loginState) error {
data, err := api.jsonCodec().Encode(*ls)
if err != nil {
return err
@ -83,7 +83,7 @@ func (api *PsiphonConfigAPIWithLogin) writestate(ls *loginState) error {
return api.KVStore.Set(loginKey, data)
}
func (api *PsiphonConfigAPIWithLogin) doRegister(ctx context.Context, password string) (string, error) {
func (api *withLoginPsiphonConfigAPI) doRegister(ctx context.Context, password string) (string, error) {
req := newRegisterRequest(password)
ls := &loginState{}
resp, err := api.RegisterAPI.Call(ctx, req)
@ -95,7 +95,7 @@ func (api *PsiphonConfigAPIWithLogin) doRegister(ctx context.Context, password s
return api.doLogin(ctx, ls)
}
func (api *PsiphonConfigAPIWithLogin) forceRegister(ctx context.Context) (string, error) {
func (api *withLoginPsiphonConfigAPI) forceRegister(ctx context.Context) (string, error) {
var password string
// If we already have a previous password, let us keep
// using it. This will allow a new version of the API to
@ -115,7 +115,7 @@ func (api *PsiphonConfigAPIWithLogin) forceRegister(ctx context.Context) (string
return api.doRegister(ctx, password)
}
func (api *PsiphonConfigAPIWithLogin) forceLogin(ctx context.Context) (string, error) {
func (api *withLoginPsiphonConfigAPI) forceLogin(ctx context.Context) (string, error) {
ls, err := api.readstate()
if err != nil {
return "", err
@ -123,7 +123,7 @@ func (api *PsiphonConfigAPIWithLogin) forceLogin(ctx context.Context) (string, e
return api.doLogin(ctx, ls)
}
func (api *PsiphonConfigAPIWithLogin) maybeLogin(ctx context.Context) (string, error) {
func (api *withLoginPsiphonConfigAPI) maybeLogin(ctx context.Context) (string, error) {
ls, _ := api.readstate()
if ls == nil || !ls.credentialsValid() {
return api.forceRegister(ctx)
@ -134,7 +134,7 @@ func (api *PsiphonConfigAPIWithLogin) maybeLogin(ctx context.Context) (string, e
return ls.Token, nil
}
func (api *PsiphonConfigAPIWithLogin) doLogin(ctx context.Context, ls *loginState) (string, error) {
func (api *withLoginPsiphonConfigAPI) doLogin(ctx context.Context, ls *loginState) (string, error) {
req := &apimodel.LoginRequest{
ClientID: ls.ClientID,
Password: ls.Password,
@ -151,19 +151,19 @@ func (api *PsiphonConfigAPIWithLogin) doLogin(ctx context.Context, ls *loginStat
return ls.Token, nil
}
var _ PsiphonConfigCaller = &PsiphonConfigAPIWithLogin{}
var _ callerForPsiphonConfigAPI = &withLoginPsiphonConfigAPI{}
// TorTargetsAPIWithLogin implements login for TorTargetsAPI.
type TorTargetsAPIWithLogin struct {
API TorTargetsCloner // mandatory
JSONCodec JSONCodec // optional
KVStore KVStore // mandatory
RegisterAPI RegisterCaller // mandatory
LoginAPI LoginCaller // mandatory
// withLoginTorTargetsAPI implements login for simpleTorTargetsAPI.
type withLoginTorTargetsAPI struct {
API clonerForTorTargetsAPI // mandatory
JSONCodec JSONCodec // optional
KVStore KVStore // mandatory
RegisterAPI callerForRegisterAPI // mandatory
LoginAPI callerForLoginAPI // mandatory
}
// Call logins, if needed, then calls the API.
func (api *TorTargetsAPIWithLogin) Call(ctx context.Context, req *apimodel.TorTargetsRequest) (apimodel.TorTargetsResponse, error) {
func (api *withLoginTorTargetsAPI) Call(ctx context.Context, req *apimodel.TorTargetsRequest) (apimodel.TorTargetsResponse, error) {
token, err := api.maybeLogin(ctx)
if err != nil {
return nil, err
@ -197,14 +197,14 @@ func (api *TorTargetsAPIWithLogin) Call(ctx context.Context, req *apimodel.TorTa
return resp, nil
}
func (api *TorTargetsAPIWithLogin) jsonCodec() JSONCodec {
func (api *withLoginTorTargetsAPI) jsonCodec() JSONCodec {
if api.JSONCodec != nil {
return api.JSONCodec
}
return &defaultJSONCodec{}
}
func (api *TorTargetsAPIWithLogin) readstate() (*loginState, error) {
func (api *withLoginTorTargetsAPI) readstate() (*loginState, error) {
data, err := api.KVStore.Get(loginKey)
if err != nil {
return nil, err
@ -216,7 +216,7 @@ func (api *TorTargetsAPIWithLogin) readstate() (*loginState, error) {
return &ls, nil
}
func (api *TorTargetsAPIWithLogin) writestate(ls *loginState) error {
func (api *withLoginTorTargetsAPI) writestate(ls *loginState) error {
data, err := api.jsonCodec().Encode(*ls)
if err != nil {
return err
@ -224,7 +224,7 @@ func (api *TorTargetsAPIWithLogin) writestate(ls *loginState) error {
return api.KVStore.Set(loginKey, data)
}
func (api *TorTargetsAPIWithLogin) doRegister(ctx context.Context, password string) (string, error) {
func (api *withLoginTorTargetsAPI) doRegister(ctx context.Context, password string) (string, error) {
req := newRegisterRequest(password)
ls := &loginState{}
resp, err := api.RegisterAPI.Call(ctx, req)
@ -236,7 +236,7 @@ func (api *TorTargetsAPIWithLogin) doRegister(ctx context.Context, password stri
return api.doLogin(ctx, ls)
}
func (api *TorTargetsAPIWithLogin) forceRegister(ctx context.Context) (string, error) {
func (api *withLoginTorTargetsAPI) forceRegister(ctx context.Context) (string, error) {
var password string
// If we already have a previous password, let us keep
// using it. This will allow a new version of the API to
@ -256,7 +256,7 @@ func (api *TorTargetsAPIWithLogin) forceRegister(ctx context.Context) (string, e
return api.doRegister(ctx, password)
}
func (api *TorTargetsAPIWithLogin) forceLogin(ctx context.Context) (string, error) {
func (api *withLoginTorTargetsAPI) forceLogin(ctx context.Context) (string, error) {
ls, err := api.readstate()
if err != nil {
return "", err
@ -264,7 +264,7 @@ func (api *TorTargetsAPIWithLogin) forceLogin(ctx context.Context) (string, erro
return api.doLogin(ctx, ls)
}
func (api *TorTargetsAPIWithLogin) maybeLogin(ctx context.Context) (string, error) {
func (api *withLoginTorTargetsAPI) maybeLogin(ctx context.Context) (string, error) {
ls, _ := api.readstate()
if ls == nil || !ls.credentialsValid() {
return api.forceRegister(ctx)
@ -275,7 +275,7 @@ func (api *TorTargetsAPIWithLogin) maybeLogin(ctx context.Context) (string, erro
return ls.Token, nil
}
func (api *TorTargetsAPIWithLogin) doLogin(ctx context.Context, ls *loginState) (string, error) {
func (api *withLoginTorTargetsAPI) doLogin(ctx context.Context, ls *loginState) (string, error) {
req := &apimodel.LoginRequest{
ClientID: ls.ClientID,
Password: ls.Password,
@ -292,4 +292,4 @@ func (api *TorTargetsAPIWithLogin) doLogin(ctx context.Context, ls *loginState)
return ls.Token, nil
}
var _ TorTargetsCaller = &TorTargetsAPIWithLogin{}
var _ callerForTorTargetsAPI = &withLoginTorTargetsAPI{}

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:52.9205436 +0100 CET m=+0.000137951
// 2021-03-10 13:17:34.605701732 +0100 CET m=+0.000131680
package ooapi
@ -16,7 +16,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
func TestRegisterAndLoginPsiphonConfigAPISuccess(t *testing.T) {
func TestRegisterAndLoginPsiphonConfigSuccess(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -31,7 +31,7 @@ func TestRegisterAndLoginPsiphonConfigAPISuccess(t *testing.T) {
Token: "antani-antani-token",
},
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Response: expect,
@ -39,7 +39,7 @@ func TestRegisterAndLoginPsiphonConfigAPISuccess(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -62,7 +62,7 @@ func TestRegisterAndLoginPsiphonConfigAPISuccess(t *testing.T) {
}
}
func TestPsiphonConfigAPIContinueUsingToken(t *testing.T) {
func TestPsiphonConfigContinueUsingToken(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -77,7 +77,7 @@ func TestPsiphonConfigAPIContinueUsingToken(t *testing.T) {
Token: "antani-antani-token",
},
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Response: expect,
@ -85,7 +85,7 @@ func TestPsiphonConfigAPIContinueUsingToken(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -135,7 +135,7 @@ func TestPsiphonConfigAPIContinueUsingToken(t *testing.T) {
}
}
func TestPsiphonConfigAPIWithValidButExpiredToken(t *testing.T) {
func TestPsiphonConfigWithValidButExpiredToken(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -149,7 +149,7 @@ func TestPsiphonConfigAPIWithValidButExpiredToken(t *testing.T) {
Token: "antani-antani-token",
},
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Response: expect,
@ -157,7 +157,7 @@ func TestPsiphonConfigAPIWithValidButExpiredToken(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
ls := &loginState{
ClientID: "antani-antani",
@ -189,7 +189,7 @@ func TestPsiphonConfigAPIWithValidButExpiredToken(t *testing.T) {
}
}
func TestPsiphonConfigAPIWithRegisterAPIError(t *testing.T) {
func TestPsiphonConfigWithRegisterAPIError(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -197,14 +197,14 @@ func TestPsiphonConfigAPIWithRegisterAPIError(t *testing.T) {
registerAPI := &FakeRegisterAPI{
Err: errMocked,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Response: expect,
},
},
RegisterAPI: registerAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -221,7 +221,7 @@ func TestPsiphonConfigAPIWithRegisterAPIError(t *testing.T) {
}
}
func TestPsiphonConfigAPIWithLoginFailure(t *testing.T) {
func TestPsiphonConfigWithLoginFailure(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -234,7 +234,7 @@ func TestPsiphonConfigAPIWithLoginFailure(t *testing.T) {
loginAPI := &FakeLoginAPI{
Err: errMocked,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Response: expect,
@ -242,7 +242,7 @@ func TestPsiphonConfigAPIWithLoginFailure(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -262,7 +262,7 @@ func TestPsiphonConfigAPIWithLoginFailure(t *testing.T) {
}
}
func TestRegisterAndLoginPsiphonConfigAPIThenFail(t *testing.T) {
func TestRegisterAndLoginPsiphonConfigThenFail(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -278,7 +278,7 @@ func TestRegisterAndLoginPsiphonConfigAPIThenFail(t *testing.T) {
},
}
errMocked := errors.New("mocked error")
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Err: errMocked,
@ -286,7 +286,7 @@ func TestRegisterAndLoginPsiphonConfigAPIThenFail(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -306,28 +306,28 @@ func TestRegisterAndLoginPsiphonConfigAPIThenFail(t *testing.T) {
}
}
func TestPsiphonConfigAPITheDatabaseIsReplaced(t *testing.T) {
func TestPsiphonConfigTheDatabaseIsReplaced(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &PsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simplePsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -366,7 +366,7 @@ func TestPsiphonConfigAPITheDatabaseIsReplaced(t *testing.T) {
}
}
func TestRegisterAndLoginPsiphonConfigAPICannotWriteState(t *testing.T) {
func TestRegisterAndLoginPsiphonConfigCannotWriteState(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
@ -382,7 +382,7 @@ func TestRegisterAndLoginPsiphonConfigAPICannotWriteState(t *testing.T) {
},
}
errMocked := errors.New("mocked error")
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: &FakePsiphonConfigAPI{
WithResult: &FakePsiphonConfigAPI{
Response: expect,
@ -390,7 +390,7 @@ func TestRegisterAndLoginPsiphonConfigAPICannotWriteState(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
JSONCodec: &FakeCodec{
EncodeErr: errMocked,
},
@ -413,13 +413,13 @@ func TestRegisterAndLoginPsiphonConfigAPICannotWriteState(t *testing.T) {
}
}
func TestPsiphonConfigAPIReadStateDecodeFailure(t *testing.T) {
func TestPsiphonConfigReadStateDecodeFailure(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.PsiphonConfigResponse
ff.fill(&expect)
errMocked := errors.New("mocked error")
login := &PsiphonConfigAPIWithLogin{
KVStore: &memkvstore{},
login := &withLoginPsiphonConfigAPI{
KVStore: &MemKVStore{},
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
ls := &loginState{
@ -440,28 +440,28 @@ func TestPsiphonConfigAPIReadStateDecodeFailure(t *testing.T) {
}
}
func TestPsiphonConfigAPITheDatabaseIsReplacedThenFailure(t *testing.T) {
func TestPsiphonConfigTheDatabaseIsReplacedThenFailure(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &PsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simplePsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -502,28 +502,28 @@ func TestPsiphonConfigAPITheDatabaseIsReplacedThenFailure(t *testing.T) {
}
}
func TestPsiphonConfigAPIClockIsOffThenSuccess(t *testing.T) {
func TestPsiphonConfigClockIsOffThenSuccess(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &PsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simplePsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -564,28 +564,28 @@ func TestPsiphonConfigAPIClockIsOffThenSuccess(t *testing.T) {
}
}
func TestPsiphonConfigAPIClockIsOffThen401(t *testing.T) {
func TestPsiphonConfigClockIsOffThen401(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &PsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simplePsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -627,28 +627,28 @@ func TestPsiphonConfigAPIClockIsOffThen401(t *testing.T) {
}
}
func TestPsiphonConfigAPIClockIsOffThen500(t *testing.T) {
func TestPsiphonConfigClockIsOffThen500(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &PsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simplePsiphonConfigAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &PsiphonConfigAPIWithLogin{
login := &withLoginPsiphonConfigAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.PsiphonConfigRequest
ff.fill(&req)
@ -690,7 +690,7 @@ func TestPsiphonConfigAPIClockIsOffThen500(t *testing.T) {
}
}
func TestRegisterAndLoginTorTargetsAPISuccess(t *testing.T) {
func TestRegisterAndLoginTorTargetsSuccess(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -705,7 +705,7 @@ func TestRegisterAndLoginTorTargetsAPISuccess(t *testing.T) {
Token: "antani-antani-token",
},
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Response: expect,
@ -713,7 +713,7 @@ func TestRegisterAndLoginTorTargetsAPISuccess(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -736,7 +736,7 @@ func TestRegisterAndLoginTorTargetsAPISuccess(t *testing.T) {
}
}
func TestTorTargetsAPIContinueUsingToken(t *testing.T) {
func TestTorTargetsContinueUsingToken(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -751,7 +751,7 @@ func TestTorTargetsAPIContinueUsingToken(t *testing.T) {
Token: "antani-antani-token",
},
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Response: expect,
@ -759,7 +759,7 @@ func TestTorTargetsAPIContinueUsingToken(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -809,7 +809,7 @@ func TestTorTargetsAPIContinueUsingToken(t *testing.T) {
}
}
func TestTorTargetsAPIWithValidButExpiredToken(t *testing.T) {
func TestTorTargetsWithValidButExpiredToken(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -823,7 +823,7 @@ func TestTorTargetsAPIWithValidButExpiredToken(t *testing.T) {
Token: "antani-antani-token",
},
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Response: expect,
@ -831,7 +831,7 @@ func TestTorTargetsAPIWithValidButExpiredToken(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
ls := &loginState{
ClientID: "antani-antani",
@ -863,7 +863,7 @@ func TestTorTargetsAPIWithValidButExpiredToken(t *testing.T) {
}
}
func TestTorTargetsAPIWithRegisterAPIError(t *testing.T) {
func TestTorTargetsWithRegisterAPIError(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -871,14 +871,14 @@ func TestTorTargetsAPIWithRegisterAPIError(t *testing.T) {
registerAPI := &FakeRegisterAPI{
Err: errMocked,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Response: expect,
},
},
RegisterAPI: registerAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -895,7 +895,7 @@ func TestTorTargetsAPIWithRegisterAPIError(t *testing.T) {
}
}
func TestTorTargetsAPIWithLoginFailure(t *testing.T) {
func TestTorTargetsWithLoginFailure(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -908,7 +908,7 @@ func TestTorTargetsAPIWithLoginFailure(t *testing.T) {
loginAPI := &FakeLoginAPI{
Err: errMocked,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Response: expect,
@ -916,7 +916,7 @@ func TestTorTargetsAPIWithLoginFailure(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -936,7 +936,7 @@ func TestTorTargetsAPIWithLoginFailure(t *testing.T) {
}
}
func TestRegisterAndLoginTorTargetsAPIThenFail(t *testing.T) {
func TestRegisterAndLoginTorTargetsThenFail(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -952,7 +952,7 @@ func TestRegisterAndLoginTorTargetsAPIThenFail(t *testing.T) {
},
}
errMocked := errors.New("mocked error")
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Err: errMocked,
@ -960,7 +960,7 @@ func TestRegisterAndLoginTorTargetsAPIThenFail(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -980,28 +980,28 @@ func TestRegisterAndLoginTorTargetsAPIThenFail(t *testing.T) {
}
}
func TestTorTargetsAPITheDatabaseIsReplaced(t *testing.T) {
func TestTorTargetsTheDatabaseIsReplaced(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &TorTargetsAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simpleTorTargetsAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -1040,7 +1040,7 @@ func TestTorTargetsAPITheDatabaseIsReplaced(t *testing.T) {
}
}
func TestRegisterAndLoginTorTargetsAPICannotWriteState(t *testing.T) {
func TestRegisterAndLoginTorTargetsCannotWriteState(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
@ -1056,7 +1056,7 @@ func TestRegisterAndLoginTorTargetsAPICannotWriteState(t *testing.T) {
},
}
errMocked := errors.New("mocked error")
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: &FakeTorTargetsAPI{
WithResult: &FakeTorTargetsAPI{
Response: expect,
@ -1064,7 +1064,7 @@ func TestRegisterAndLoginTorTargetsAPICannotWriteState(t *testing.T) {
},
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
JSONCodec: &FakeCodec{
EncodeErr: errMocked,
},
@ -1087,13 +1087,13 @@ func TestRegisterAndLoginTorTargetsAPICannotWriteState(t *testing.T) {
}
}
func TestTorTargetsAPIReadStateDecodeFailure(t *testing.T) {
func TestTorTargetsReadStateDecodeFailure(t *testing.T) {
ff := &fakeFill{}
var expect apimodel.TorTargetsResponse
ff.fill(&expect)
errMocked := errors.New("mocked error")
login := &TorTargetsAPIWithLogin{
KVStore: &memkvstore{},
login := &withLoginTorTargetsAPI{
KVStore: &MemKVStore{},
JSONCodec: &FakeCodec{DecodeErr: errMocked},
}
ls := &loginState{
@ -1114,28 +1114,28 @@ func TestTorTargetsAPIReadStateDecodeFailure(t *testing.T) {
}
}
func TestTorTargetsAPITheDatabaseIsReplacedThenFailure(t *testing.T) {
func TestTorTargetsTheDatabaseIsReplacedThenFailure(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &TorTargetsAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simpleTorTargetsAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -1176,28 +1176,28 @@ func TestTorTargetsAPITheDatabaseIsReplacedThenFailure(t *testing.T) {
}
}
func TestTorTargetsAPIClockIsOffThenSuccess(t *testing.T) {
func TestTorTargetsClockIsOffThenSuccess(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &TorTargetsAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simpleTorTargetsAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -1238,28 +1238,28 @@ func TestTorTargetsAPIClockIsOffThenSuccess(t *testing.T) {
}
}
func TestTorTargetsAPIClockIsOffThen401(t *testing.T) {
func TestTorTargetsClockIsOffThen401(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &TorTargetsAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simpleTorTargetsAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)
@ -1301,28 +1301,28 @@ func TestTorTargetsAPIClockIsOffThen401(t *testing.T) {
}
}
func TestTorTargetsAPIClockIsOffThen500(t *testing.T) {
func TestTorTargetsClockIsOffThen500(t *testing.T) {
ff := &fakeFill{}
handler := &LoginHandler{t: t}
srvr := httptest.NewServer(handler)
defer srvr.Close()
registerAPI := &RegisterAPI{
HTTPClient: &VerboseHTTPClient{t: t},
registerAPI := &simpleRegisterAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
loginAPI := &LoginAPI{
HTTPClient: &VerboseHTTPClient{t: t},
loginAPI := &simpleLoginAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
baseAPI := &TorTargetsAPI{
HTTPClient: &VerboseHTTPClient{t: t},
baseAPI := &simpleTorTargetsAPI{
HTTPClient: &VerboseHTTPClient{T: t},
BaseURL: srvr.URL,
}
login := &TorTargetsAPIWithLogin{
login := &withLoginTorTargetsAPI{
API: baseAPI,
RegisterAPI: registerAPI,
LoginAPI: loginAPI,
KVStore: &memkvstore{},
KVStore: &MemKVStore{},
}
var req *apimodel.TorTargetsRequest
ff.fill(&req)

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:53.210720456 +0100 CET m=+0.000083649
// 2021-03-10 13:17:35.068399906 +0100 CET m=+0.000095438
package ooapi
@ -14,7 +14,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
func (api *CheckReportIDAPI) newRequest(ctx context.Context, req *apimodel.CheckReportIDRequest) (*http.Request, error) {
func (api *simpleCheckReportIDAPI) newRequest(ctx context.Context, req *apimodel.CheckReportIDRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -29,7 +29,7 @@ func (api *CheckReportIDAPI) newRequest(ctx context.Context, req *apimodel.Check
return api.requestMaker().NewRequest(ctx, "GET", URL.String(), nil)
}
func (api *CheckInAPI) newRequest(ctx context.Context, req *apimodel.CheckInRequest) (*http.Request, error) {
func (api *simpleCheckInAPI) newRequest(ctx context.Context, req *apimodel.CheckInRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -47,7 +47,7 @@ func (api *CheckInAPI) newRequest(ctx context.Context, req *apimodel.CheckInRequ
return out, nil
}
func (api *LoginAPI) newRequest(ctx context.Context, req *apimodel.LoginRequest) (*http.Request, error) {
func (api *simpleLoginAPI) newRequest(ctx context.Context, req *apimodel.LoginRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -65,7 +65,7 @@ func (api *LoginAPI) newRequest(ctx context.Context, req *apimodel.LoginRequest)
return out, nil
}
func (api *MeasurementMetaAPI) newRequest(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*http.Request, error) {
func (api *simpleMeasurementMetaAPI) newRequest(ctx context.Context, req *apimodel.MeasurementMetaRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -86,7 +86,7 @@ func (api *MeasurementMetaAPI) newRequest(ctx context.Context, req *apimodel.Mea
return api.requestMaker().NewRequest(ctx, "GET", URL.String(), nil)
}
func (api *RegisterAPI) newRequest(ctx context.Context, req *apimodel.RegisterRequest) (*http.Request, error) {
func (api *simpleRegisterAPI) newRequest(ctx context.Context, req *apimodel.RegisterRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -104,7 +104,7 @@ func (api *RegisterAPI) newRequest(ctx context.Context, req *apimodel.RegisterRe
return out, nil
}
func (api *TestHelpersAPI) newRequest(ctx context.Context, req *apimodel.TestHelpersRequest) (*http.Request, error) {
func (api *simpleTestHelpersAPI) newRequest(ctx context.Context, req *apimodel.TestHelpersRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -113,7 +113,7 @@ func (api *TestHelpersAPI) newRequest(ctx context.Context, req *apimodel.TestHel
return api.requestMaker().NewRequest(ctx, "GET", URL.String(), nil)
}
func (api *PsiphonConfigAPI) newRequest(ctx context.Context, req *apimodel.PsiphonConfigRequest) (*http.Request, error) {
func (api *simplePsiphonConfigAPI) newRequest(ctx context.Context, req *apimodel.PsiphonConfigRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -122,7 +122,7 @@ func (api *PsiphonConfigAPI) newRequest(ctx context.Context, req *apimodel.Psiph
return api.requestMaker().NewRequest(ctx, "GET", URL.String(), nil)
}
func (api *TorTargetsAPI) newRequest(ctx context.Context, req *apimodel.TorTargetsRequest) (*http.Request, error) {
func (api *simpleTorTargetsAPI) newRequest(ctx context.Context, req *apimodel.TorTargetsRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -131,7 +131,7 @@ func (api *TorTargetsAPI) newRequest(ctx context.Context, req *apimodel.TorTarge
return api.requestMaker().NewRequest(ctx, "GET", URL.String(), nil)
}
func (api *URLsAPI) newRequest(ctx context.Context, req *apimodel.URLsRequest) (*http.Request, error) {
func (api *simpleURLsAPI) newRequest(ctx context.Context, req *apimodel.URLsRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -151,7 +151,7 @@ func (api *URLsAPI) newRequest(ctx context.Context, req *apimodel.URLsRequest) (
return api.requestMaker().NewRequest(ctx, "GET", URL.String(), nil)
}
func (api *OpenReportAPI) newRequest(ctx context.Context, req *apimodel.OpenReportRequest) (*http.Request, error) {
func (api *simpleOpenReportAPI) newRequest(ctx context.Context, req *apimodel.OpenReportRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err
@ -169,7 +169,7 @@ func (api *OpenReportAPI) newRequest(ctx context.Context, req *apimodel.OpenRepo
return out, nil
}
func (api *SubmitMeasurementAPI) newRequest(ctx context.Context, req *apimodel.SubmitMeasurementRequest) (*http.Request, error) {
func (api *simpleSubmitMeasurementAPI) newRequest(ctx context.Context, req *apimodel.SubmitMeasurementRequest) (*http.Request, error) {
URL, err := url.Parse(api.baseURL())
if err != nil {
return nil, err

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:53.567815989 +0100 CET m=+0.000158731
// 2021-03-10 13:17:35.43791782 +0100 CET m=+0.000136842
package ooapi
@ -13,7 +13,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/ooapi/apimodel"
)
func (api *CheckReportIDAPI) newResponse(resp *http.Response, err error) (*apimodel.CheckReportIDResponse, error) {
func (api *simpleCheckReportIDAPI) newResponse(resp *http.Response, err error) (*apimodel.CheckReportIDResponse, error) {
if err != nil {
return nil, err
}
@ -36,7 +36,7 @@ func (api *CheckReportIDAPI) newResponse(resp *http.Response, err error) (*apimo
return out, nil
}
func (api *CheckInAPI) newResponse(resp *http.Response, err error) (*apimodel.CheckInResponse, error) {
func (api *simpleCheckInAPI) newResponse(resp *http.Response, err error) (*apimodel.CheckInResponse, error) {
if err != nil {
return nil, err
}
@ -59,7 +59,7 @@ func (api *CheckInAPI) newResponse(resp *http.Response, err error) (*apimodel.Ch
return out, nil
}
func (api *LoginAPI) newResponse(resp *http.Response, err error) (*apimodel.LoginResponse, error) {
func (api *simpleLoginAPI) newResponse(resp *http.Response, err error) (*apimodel.LoginResponse, error) {
if err != nil {
return nil, err
}
@ -82,7 +82,7 @@ func (api *LoginAPI) newResponse(resp *http.Response, err error) (*apimodel.Logi
return out, nil
}
func (api *MeasurementMetaAPI) newResponse(resp *http.Response, err error) (*apimodel.MeasurementMetaResponse, error) {
func (api *simpleMeasurementMetaAPI) newResponse(resp *http.Response, err error) (*apimodel.MeasurementMetaResponse, error) {
if err != nil {
return nil, err
}
@ -105,7 +105,7 @@ func (api *MeasurementMetaAPI) newResponse(resp *http.Response, err error) (*api
return out, nil
}
func (api *RegisterAPI) newResponse(resp *http.Response, err error) (*apimodel.RegisterResponse, error) {
func (api *simpleRegisterAPI) newResponse(resp *http.Response, err error) (*apimodel.RegisterResponse, error) {
if err != nil {
return nil, err
}
@ -128,7 +128,7 @@ func (api *RegisterAPI) newResponse(resp *http.Response, err error) (*apimodel.R
return out, nil
}
func (api *TestHelpersAPI) newResponse(resp *http.Response, err error) (apimodel.TestHelpersResponse, error) {
func (api *simpleTestHelpersAPI) newResponse(resp *http.Response, err error) (apimodel.TestHelpersResponse, error) {
if err != nil {
return nil, err
}
@ -154,7 +154,7 @@ func (api *TestHelpersAPI) newResponse(resp *http.Response, err error) (apimodel
return out, nil
}
func (api *PsiphonConfigAPI) newResponse(resp *http.Response, err error) (apimodel.PsiphonConfigResponse, error) {
func (api *simplePsiphonConfigAPI) newResponse(resp *http.Response, err error) (apimodel.PsiphonConfigResponse, error) {
if err != nil {
return nil, err
}
@ -180,7 +180,7 @@ func (api *PsiphonConfigAPI) newResponse(resp *http.Response, err error) (apimod
return out, nil
}
func (api *TorTargetsAPI) newResponse(resp *http.Response, err error) (apimodel.TorTargetsResponse, error) {
func (api *simpleTorTargetsAPI) newResponse(resp *http.Response, err error) (apimodel.TorTargetsResponse, error) {
if err != nil {
return nil, err
}
@ -206,7 +206,7 @@ func (api *TorTargetsAPI) newResponse(resp *http.Response, err error) (apimodel.
return out, nil
}
func (api *URLsAPI) newResponse(resp *http.Response, err error) (*apimodel.URLsResponse, error) {
func (api *simpleURLsAPI) newResponse(resp *http.Response, err error) (*apimodel.URLsResponse, error) {
if err != nil {
return nil, err
}
@ -229,7 +229,7 @@ func (api *URLsAPI) newResponse(resp *http.Response, err error) (*apimodel.URLsR
return out, nil
}
func (api *OpenReportAPI) newResponse(resp *http.Response, err error) (*apimodel.OpenReportResponse, error) {
func (api *simpleOpenReportAPI) newResponse(resp *http.Response, err error) (*apimodel.OpenReportResponse, error) {
if err != nil {
return nil, err
}
@ -252,7 +252,7 @@ func (api *OpenReportAPI) newResponse(resp *http.Response, err error) (*apimodel
return out, nil
}
func (api *SubmitMeasurementAPI) newResponse(resp *http.Response, err error) (*apimodel.SubmitMeasurementResponse, error) {
func (api *simpleSubmitMeasurementAPI) newResponse(resp *http.Response, err error) (*apimodel.SubmitMeasurementResponse, error) {
if err != nil {
return nil, err
}

View File

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT.
// 2021-02-26 15:45:53.881261959 +0100 CET m=+0.000594905
// 2021-03-10 13:17:35.72281221 +0100 CET m=+0.000577472
package ooapi
@ -9,7 +9,7 @@ const swagger = `{
"swagger": "2.0",
"info": {
"title": "OONI API specification",
"version": "0.20210226.2144553"
"version": "0.20210310.3121735"
},
"host": "api.ooni.io",
"basePath": "/",