Skip to content

Commit

Permalink
Merge pull request #7 from programmfabrik/revert-6-datastore_get_slic…
Browse files Browse the repository at this point in the history
…e_support

Revert "Datastore.Get Slice and Map Support"
  • Loading branch information
simonfrey authored Mar 21, 2019
2 parents 0605659 + 05cc772 commit e6c69d8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 117 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,6 @@ The method `store_respsonse_qjson` takes only **string** as value. This qjson-st
### Get Data from Custom Store

The data from the custom store is retrieved using the `datastore <key>`Template function. `key`must be used in any store method before it is requested. If the key is unset, the datastore function returns an empty **string**. Use the special key `-` to return the entire datastore.
You can also use the slice and map notation for getting certain values out of the slice or map directly: `mySlice[3]` would return
the value at index `3` of the slice that is stored with the key `mySlice` in the datastore.

### Get Data from Sequential Store

Expand Down
34 changes: 28 additions & 6 deletions api_testcase.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ const (
// Case defines the structure of our single testcase
// It gets read in by our config reader at the moment the mainfest.json gets parsed
type Case struct {
Name string `json:"name"`
RequestData *util.GenericJson `json:"request"`
ResponseData util.GenericJson `json:"response"`
Name string `json:"name"`
RequestData *util.GenericJson `json:"request"`
TypedResponseData *CaseResponse `json:"response"`
responseData util.GenericJson
ContinueOnFailure bool `json:"continue_on_failure"`
Store map[string]interface{} `json:"store"` // init datastore before testrun
StoreResponse map[string]string `json:"store_response_qjson"` // store qjson parsed response in datastore
Expand All @@ -49,6 +50,11 @@ type Case struct {
ServerURL string
}

type CaseResponse struct {
Statuscode int `json:"statuscode"`
Body util.GenericJson `json:"body"`
}

func (testCase Case) runAPITestCase() (success bool) {
if testCase.LogVerbosity != nil && *testCase.LogVerbosity > FylrConfig.Apitest.LogVerbosity {
defer FylrConfig.SetLogVerbosity(FylrConfig.Apitest.LogVerbosity)
Expand All @@ -63,6 +69,22 @@ func (testCase Case) runAPITestCase() (success bool) {
log.Infof(" [%2d] '<no name>'", testCase.index)
}

//Marshal external datastructure in our internal used reponseData
jsonResponse, err := json.Marshal(testCase.TypedResponseData)
if err != nil {
err = fmt.Errorf("error marshaling TypedResponseData: %s", err)
r.SaveToReportLog(fmt.Sprintf("Error during execution: %s", err))
log.Errorf(" [%2d] %s", testCase.index, err)
return false
}
err = json.Unmarshal(jsonResponse, &testCase.responseData)
if err != nil {
err = fmt.Errorf("error unmarshaling into responseData: %s", err)
r.SaveToReportLog(fmt.Sprintf("Error during execution: %s", err))
log.Errorf(" [%2d] %s", testCase.index, err)
return false
}

r.NewChild(testCase.Name)

start := time.Now()
Expand All @@ -74,7 +96,7 @@ func (testCase Case) runAPITestCase() (success bool) {
log.Errorf(" [%2d] %s", testCase.index, err)
return false
}
err := testCase.dataStore.SetMap(testCase.Store)
err = testCase.dataStore.SetMap(testCase.Store)
if err != nil {
err = fmt.Errorf("error setting datastore map:%s", err)
r.SaveToReportLog(fmt.Sprintf("Error during execution: %s", err))
Expand Down Expand Up @@ -373,10 +395,10 @@ func (testCase Case) loadRequest() (req api.Request, err error) {

func (testCase Case) loadResponse() (res api.Response, err error) {
// unspecified response is interpreted as status_code 200
if testCase.ResponseData == nil {
if testCase.responseData == nil {
return api.NewResponse(200, nil, bytes.NewReader([]byte("")))
}
spec, err := testCase.loadResponseSerialization(testCase.ResponseData)
spec, err := testCase.loadResponseSerialization(testCase.responseData)
if err != nil {
return res, fmt.Errorf("error loading response spec: %s", err)
}
Expand Down
58 changes: 2 additions & 56 deletions api_testcase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,62 +413,8 @@ func TestHeaderFromDatastoreWithMap(t *testing.T) {
test.runAPITestCase()

r.GetTestResult(report.ParseJSONResult)
if r.DidFail() {
t.Errorf("Did fail but it should not")
}

}

func TestHeaderFromDatastoreWithSlice(t *testing.T) {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"Auth": "%s"}`, r.Header.Get("AuthHeader"))
}))
defer ts.Close()

testManifest := []byte(`
{
"name": "CollectTest",
"request":{
"endpoint": "suggest",
"method": "GET",
"header_from_store":{
"authHeader":"hallo[3]"
}
},
"response":{
"body": {
"Auth": "es index"
}
}
}
`)

filesystem.Fs = afero.NewMemMapFs()
afero.WriteFile(filesystem.Fs, "manifest.json", []byte(testManifest), 644)

r := report.NewReport()

var test Case
err := json.Unmarshal(testManifest, &test)
if err != nil {
t.Fatal(err)
}
test.reporter = r
test.ServerURL = ts.URL

test.dataStore = api.NewStore()
test.dataStore.Set("hallo[]", "du index")
test.dataStore.Set("hallo[]", "sie index")
test.dataStore.Set("hallo[]", "er index")
test.dataStore.Set("hallo[]", "es index")
test.dataStore.Set("hallo[]", "mama index")

test.runAPITestCase()

r.GetTestResult(report.ParseJSONResult)
if r.DidFail() {
t.Errorf("Did fail but it should not")
if !r.DidFail() {
t.Errorf("Did not fail but it should")
}

}
8 changes: 4 additions & 4 deletions api_testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ func NewTestSuite(

manifest, err := suite.loadManifest()
if err != nil {
return suite, fmt.Errorf("error loading manifest: %s. File: %s", err, manifestPath)
return suite, fmt.Errorf("error loading manifest: %s", err)
}

if err = cjson.Unmarshal(manifest, &suite); err != nil {
return suite, fmt.Errorf("error unmarshaling manifest: %s. File: %s", err, manifestPath)
return suite, fmt.Errorf("error unmarshaling manifest '%s': %s", manifestPath, err)
}

//Append suite manifest path to name, so we know in an automatic setup where the test is loaded from
Expand All @@ -70,7 +70,7 @@ func NewTestSuite(
// init store
err = suite.datastore.SetMap(suite.Store)
if err != nil {
err = fmt.Errorf("error setting datastore map: %s. File: %s", err, manifestPath)
err = fmt.Errorf("error setting datastore map:%s", err)
}

return suite, nil
Expand Down Expand Up @@ -237,7 +237,7 @@ func (ats Suite) loadManifest() (res []byte, err error) {
loader := template.NewLoader(ats.datastore)
manifestFile, err := filesystem.Fs.Open(ats.manifestPath)
if err != nil {
return res, fmt.Errorf("error opening manifestPath: %s. File: %s", err, ats.manifestPath)
return res, fmt.Errorf("error opening manifestPath: %s", err)
}
defer manifestFile.Close()

Expand Down
65 changes: 16 additions & 49 deletions lib/api/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (this *Datastore) Set(index string, value interface{}) error {
return nil
}

func (this Datastore) Get(index string) (res interface{}, err error) {
func (this Datastore) Get(index string) (interface{}, error) {
// strings are evalulated as int, so
// that we can support "-<int>" notations

Expand All @@ -146,57 +146,24 @@ func (this Datastore) Get(index string) (res interface{}, err error) {
return this.storage, nil
}

var dsMapRegex = regexp.MustCompile(`^(.*?)\[(.+?)\]$`)

if rego := dsMapRegex.FindStringSubmatch(index); len(rego) > 0 {
//we have a map or slice
useIndex := rego[1]
mapIndex := rego[2]

tmpRes, ok := this.storage[useIndex]
if !ok {
log.Errorf("datastore: key: %s not found.", useIndex)
return "", nil
idx, err := strconv.Atoi(index)
if err == nil {
if idx < 0 {
idx = idx + len(this.responseJson)
}

tmpResMap, ok := tmpRes.(map[string]interface{})
if ok {
//We have a map
return tmpResMap[mapIndex], nil
}

tmpResSlice, ok := tmpRes.([]interface{})
if ok {
//We have a slice
mapIdx, err := strconv.Atoi(mapIndex)
if err != nil {
log.Errorf("datastore: could not convert key to int: %s", mapIndex)
return "", nil
}

return tmpResSlice[mapIdx], nil
if idx >= len(this.responseJson) || idx < 0 {
// index out of range
return "", DatastoreIndexOutOfBoundsError{error: fmt.Sprintf("datastore.Get: idx out of range: %d, current length: %d", idx, len(this.responseJson))}
}
return this.responseJson[idx], nil
}

} else {
res, ok := this.storage[index]

idx, err := strconv.Atoi(index)
if err == nil {
if idx < 0 {
idx = idx + len(this.responseJson)
}
if idx >= len(this.responseJson) || idx < 0 {
// index out of range
return "", DatastoreIndexOutOfBoundsError{error: fmt.Sprintf("datastore.Get: idx out of range: %d, current length: %d", idx, len(this.responseJson))}
}
return this.responseJson[idx], nil
}
var ok bool
res, ok = this.storage[index]
if ok {
return res, nil
}
// logging.Warnf("datastore: %s", store.storage)
if !ok {
// logging.Warnf("datastore: key: %s not found.", index)
return "", nil
}

log.Errorf("datastore: key: %s not found.", index)
return "", nil
return res, nil
}

0 comments on commit e6c69d8

Please sign in to comment.