github.com/jonaz/heapster@v1.3.0-beta.0.0.20170208112634-cd3c15ca3d29/metrics/sinks/monasca/init_test.go (about)

     1  // Copyright 2015 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package monasca
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"io/ioutil"
    21  	"net/http"
    22  	"net/http/httptest"
    23  	"net/url"
    24  	"os"
    25  	"sync"
    26  	"testing"
    27  
    28  	"github.com/stretchr/testify/mock"
    29  )
    30  
    31  type keystoneClientMock struct {
    32  	*KeystoneClientImpl
    33  	mock.Mock
    34  }
    35  
    36  func (ks *keystoneClientMock) MonascaURL() (*url.URL, error) {
    37  	args := ks.Called()
    38  	return args.Get(0).(*url.URL), args.Error(1)
    39  }
    40  
    41  func (ks *keystoneClientMock) GetToken() (string, error) {
    42  	args := ks.Called()
    43  	return args.String(0), args.Error(1)
    44  }
    45  
    46  var monascaAPIStub *httptest.Server
    47  var keystoneAPIStub *httptest.Server
    48  
    49  type ksAuthRequest struct {
    50  	Auth ksAuth `json:"auth"`
    51  }
    52  
    53  type ksAuth struct {
    54  	Identity ksIdentity `json:"identity"`
    55  	Scope    ksScope    `json:"scope"`
    56  }
    57  
    58  type ksIdentity struct {
    59  	Methods  []string   `json:"methods"`
    60  	Password ksPassword `json:"password"`
    61  }
    62  
    63  type ksPassword struct {
    64  	User ksUser `json:"user"`
    65  }
    66  
    67  type ksUser struct {
    68  	ID       string `json:"id"`
    69  	Password string `json:"password"`
    70  }
    71  
    72  type ksScope struct {
    73  	Project ksProject `json:"project"`
    74  }
    75  
    76  type ksProject struct {
    77  	ID string `json:"id"`
    78  }
    79  
    80  // prepare before testing
    81  func TestMain(m *testing.M) {
    82  	// monasca stub
    83  	monascaMutex := &sync.Mutex{}
    84  	defer monascaAPIStub.Close()
    85  	monascaAPIStub = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    86  		monascaMutex.Lock()
    87  		defer monascaMutex.Unlock()
    88  		w.Header().Set("Content-Type", "application/json")
    89  		switch r.URL.Path {
    90  		case "/metrics":
    91  			defer r.Body.Close()
    92  			contents, err := ioutil.ReadAll(r.Body)
    93  			if err != nil {
    94  				w.WriteHeader(http.StatusInternalServerError)
    95  				w.Write([]byte(fmt.Sprintf("%s", err)))
    96  				break
    97  			}
    98  
    99  			// umarshal & do type checking on the fly
   100  			metrics := []metric{}
   101  			err = json.Unmarshal(contents, &metrics)
   102  			if err != nil {
   103  				w.WriteHeader(http.StatusInternalServerError)
   104  				w.Write([]byte(fmt.Sprintf("%s", err)))
   105  				break
   106  			}
   107  
   108  			// check for empty dimensions
   109  			for _, metric := range metrics {
   110  				for _, dimVal := range metric.Dimensions {
   111  					if dimVal == "" {
   112  						w.WriteHeader(http.StatusInternalServerError)
   113  						w.Write([]byte(monEmptyDimResp))
   114  						break
   115  					}
   116  				}
   117  			}
   118  
   119  			// check token
   120  			token := r.Header.Get("X-Auth-Token")
   121  			if token != testToken {
   122  				w.WriteHeader(http.StatusUnauthorized)
   123  				w.Write([]byte(monUnauthorizedResp))
   124  				break
   125  			}
   126  			w.WriteHeader(http.StatusNoContent)
   127  			break
   128  		case "/versions":
   129  			w.WriteHeader(http.StatusOK)
   130  			break
   131  		}
   132  	}))
   133  
   134  	// keystone stub
   135  	keystoneMutex := &sync.Mutex{}
   136  	defer keystoneAPIStub.Close()
   137  	keystoneAPIStub = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   138  		keystoneMutex.Lock()
   139  		defer keystoneMutex.Unlock()
   140  		w.Header().Add("Content-Type", "application/json")
   141  		switch r.URL.Path {
   142  		case "/":
   143  			w.Write([]byte(ksVersionResp))
   144  			break
   145  		case "/v3/auth/tokens":
   146  			if r.Method == "HEAD" {
   147  				ksToken := r.Header.Get("X-Auth-Token")
   148  				if ksToken != testToken {
   149  					w.WriteHeader(http.StatusUnauthorized)
   150  					break
   151  				}
   152  				token := r.Header.Get("X-Subject-Token")
   153  				if token == testToken {
   154  					// token valid
   155  					w.WriteHeader(http.StatusNoContent)
   156  					break
   157  				}
   158  				// token invalid
   159  				w.WriteHeader(http.StatusNotFound)
   160  				break
   161  			}
   162  
   163  			// read request
   164  			defer r.Body.Close()
   165  			contents, err := ioutil.ReadAll(r.Body)
   166  			if err != nil {
   167  				w.WriteHeader(http.StatusInternalServerError)
   168  				return
   169  			}
   170  			req := ksAuthRequest{}
   171  			err = json.Unmarshal(contents, &req)
   172  			if err != nil {
   173  				w.WriteHeader(http.StatusInternalServerError)
   174  				return
   175  			}
   176  
   177  			// authenticate
   178  			if req.Auth.Identity.Password.User.ID != testConfig.UserID ||
   179  				req.Auth.Identity.Password.User.Password != testConfig.Password {
   180  				w.WriteHeader(http.StatusUnauthorized)
   181  				return
   182  			}
   183  
   184  			// check if the request is for a scoped token
   185  			returnedToken := testToken
   186  			returnedBody := ksUnscopedAuthResp
   187  			if req.Auth.Scope.Project.ID != "" {
   188  				if req.Auth.Scope.Project.ID != testTenantID {
   189  					w.WriteHeader(http.StatusInternalServerError)
   190  					return
   191  				}
   192  				returnedToken = testScopedToken
   193  				returnedBody = ksScopedAuthResp
   194  			}
   195  			// return a token
   196  			w.Header().Add("X-Subject-Token", returnedToken)
   197  			w.WriteHeader(http.StatusAccepted)
   198  			w.Write([]byte(returnedBody))
   199  			break
   200  		case "/v3/services":
   201  			w.Write([]byte(ksServicesResp))
   202  			break
   203  		case "/v3/endpoints":
   204  			w.Write([]byte(ksEndpointsResp))
   205  		default:
   206  			w.WriteHeader(http.StatusInternalServerError)
   207  		}
   208  	}))
   209  	initKeystoneRespStubs()
   210  
   211  	testConfig.Password = "bar"
   212  	testConfig.UserID = "0ca8f6"
   213  	testConfig.IdentityEndpoint = keystoneAPIStub.URL + "/v3"
   214  	os.Exit(m.Run())
   215  }