Skip to content

Commit 2b61d5b

Browse files
Add test coverage for the new API /v4/user/<uuid>/active-signature vs old v2 one
Signed-off-by: Lukasz Gryglicki <[email protected]>
1 parent 2b8a2aa commit 2b61d5b

File tree

3 files changed

+182
-2
lines changed

3 files changed

+182
-2
lines changed

tests/py2go/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@
2121
- Manually via `cURL`: `` curl -s -XGET http://127.0.0.1:5001/v4/project-compat/01af041c-fa69-4052-a23c-fb8c1d3bef24 | jq . ``.
2222
- To manually see given project values if APIs differ (to dewbug): `` aws --region us-east-1 --profile lfproduct-dev dynamodb get-item --table-name cla-dev-projects --key '{"project_id": {"S": "4a855799-0aea-4e01-98b7-ef3da09df478"}}' | jq '.Item' ``.
2323
- And `` aws --region us-east-1 --profile lfproduct-dev dynamodb query --table-name cla-dev-projects-cla-groups --index-name cla-group-id-index --key-condition-expression "cla_group_id = :project_id" --expression-attribute-values '{":project_id":{"S":"4a855799-0aea-4e01-98b7-ef3da09df478"}}' | jq '.Items' ``.
24+
- `` DEBUG='' USER_UUID=b817eb57-045a-4fe0-8473-fbb416a01d70 PY_API_URL=https://api.lfcla.dev.platform.linuxfoundation.org go test -v -run '^TestUserActiveSignatureAPI$' ``.
25+
- `` REPO_ID=466156917 PR_ID=3 DEBUG=1 go test -v -run '^TestUserActiveSignatureAPI$' ``.
26+
- `` MAX_PARALLEL=2 DEBUG='' go test -v -run '^TestAllUserActiveSignatureAPI$' ``.

tests/py2go/api_test.go

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import (
1717
"github.com/stretchr/testify/assert"
1818
)
1919

20+
const (
21+
ExampleRepoID = 466156917
22+
ExamplePRNumber = 3
23+
)
24+
2025
var (
2126
TOKEN string
2227
XACL string
@@ -25,6 +30,9 @@ var (
2530
DEBUG bool
2631
MAX_PARALLEL int
2732
PROJECT_UUID string
33+
USER_UUID string
34+
REPO_ID int64
35+
PR_ID int64
2836
ProjectAPIPath = [3]string{"/v2/project/%s", "/v4/project/%s", "/v4/project-compat/%s"}
2937
ProjectAPIKeyMapping = map[string]string{
3038
"date_created": "dateCreated",
@@ -75,6 +83,14 @@ var (
7583
"gitlab_repos": "repository_name",
7684
"gerrit_repos": "gerrit_url",
7785
}
86+
UserActiveSignatureAPIPath = [2]string{"/v2/user/%s/active-signature", "/v4/user/%s/active-signature"}
87+
UserActiveSignatureAPIKeyMapping = map[string]interface{}{
88+
"project_id": nil,
89+
"pull_request_id": nil,
90+
"repository_id": nil,
91+
"return_url": nil,
92+
"user_id": nil,
93+
}
7894
)
7995

8096
func init() {
@@ -103,6 +119,27 @@ func init() {
103119
}
104120
}
105121
PROJECT_UUID = os.Getenv("PROJECT_UUID")
122+
USER_UUID = os.Getenv("USER_UUID")
123+
REPO_ID = ExampleRepoID
124+
par = os.Getenv("REPO_ID")
125+
if par != "" {
126+
iPar, err := strconv.ParseInt(par, 10, 64)
127+
if err != nil {
128+
fmt.Printf("REPO_ID environment value should be integer >= 1\n")
129+
} else if iPar > 0 {
130+
REPO_ID = iPar
131+
}
132+
}
133+
PR_ID = ExamplePRNumber
134+
par = os.Getenv("PR_ID")
135+
if par != "" {
136+
iPar, err := strconv.ParseInt(par, 10, 64)
137+
if err != nil {
138+
fmt.Printf("PR_ID environment value should be integer >= 1\n")
139+
} else if iPar > 0 {
140+
PR_ID = iPar
141+
}
142+
}
106143
}
107144

108145
func tryParseTime(val interface{}) (time.Time, bool) {
@@ -484,3 +521,140 @@ func TestProjectAPI(t *testing.T) {
484521
Debugf("new keys: %+v\n", nky)
485522
}
486523
}
524+
525+
func runUserActiveSignatureAPIForUser(t *testing.T, userId string) {
526+
apiURL := PY_API_URL + fmt.Sprintf(UserActiveSignatureAPIPath[0], userId)
527+
Debugf("Py API call: %s\n", apiURL)
528+
oldResp, err := http.Get(apiURL)
529+
if err != nil {
530+
t.Fatalf("Failed to call API: %v", err)
531+
}
532+
assert.Equal(t, http.StatusOK, oldResp.StatusCode, "Expected 200 from PY API")
533+
defer oldResp.Body.Close()
534+
oldBody, _ := io.ReadAll(oldResp.Body)
535+
var oldJSON interface{}
536+
err = json.Unmarshal(oldBody, &oldJSON)
537+
assert.NoError(t, err)
538+
Debugf("Py raw response: %+v\n", string(oldBody))
539+
Debugf("Py response: %+v\n", oldJSON)
540+
541+
apiURL = GO_API_URL + fmt.Sprintf(UserActiveSignatureAPIPath[1], userId)
542+
Debugf("Go API call: %s\n", apiURL)
543+
newResp, err := http.Get(apiURL)
544+
if err != nil {
545+
t.Fatalf("Failed to call API: %v", err)
546+
}
547+
assert.Equal(t, http.StatusOK, newResp.StatusCode, "Expected 200 from GO API")
548+
defer newResp.Body.Close()
549+
newBody, _ := io.ReadAll(newResp.Body)
550+
var newJSON interface{}
551+
err = json.Unmarshal(newBody, &newJSON)
552+
assert.NoError(t, err)
553+
Debugf("Go raw Response: %+v\n", string(newBody))
554+
Debugf("Go response: %+v\n", newJSON)
555+
556+
if string(oldBody) == "null" && string(newBody) == "null" {
557+
return
558+
}
559+
560+
oldMap, ok1 := oldJSON.(map[string]interface{})
561+
newMap, ok2 := newJSON.(map[string]interface{})
562+
563+
if !ok1 || !ok2 {
564+
t.Fatalf("Expected both responses to be JSON objects")
565+
}
566+
compareNestedFields(t, oldMap, newMap, UserActiveSignatureAPIKeyMapping, map[string]string{})
567+
568+
if DEBUG {
569+
oky := []string{}
570+
for k, _ := range oldMap {
571+
oky = append(oky, k)
572+
}
573+
sort.Strings(oky)
574+
nky := []string{}
575+
for k, _ := range newMap {
576+
nky = append(nky, k)
577+
}
578+
sort.Strings(nky)
579+
Debugf("old keys: %+v\n", oky)
580+
Debugf("new keys: %+v\n", nky)
581+
}
582+
}
583+
584+
func TestUserActiveSignatureAPI(t *testing.T) {
585+
userId := USER_UUID
586+
if userId == "" {
587+
userId = uuid.New().String()
588+
projectId := uuid.New().String()
589+
key := "active_signature:" + userId
590+
expire := time.Now().Add(time.Hour).Unix()
591+
value, err := json.Marshal(map[string]interface{}{
592+
"user_id": userId,
593+
"project_id": projectId,
594+
"repository_id": fmt.Sprintf("%d", REPO_ID),
595+
"pull_request_id": fmt.Sprintf("%d", PR_ID),
596+
})
597+
if err != nil {
598+
t.Fatalf("failed to marshal value: %+v", err)
599+
}
600+
putTestItem("projects", "project_id", projectId, "S", map[string]interface{}{}, DEBUG)
601+
putTestItem("store", "key", key, "S", map[string]interface{}{
602+
"value": string(value),
603+
"expire": expire,
604+
}, DEBUG)
605+
defer deleteTestItem("projects", "project_id", projectId, "S", DEBUG)
606+
defer deleteTestItem("store", "key", key, "S", DEBUG)
607+
}
608+
609+
runUserActiveSignatureAPIForUser(t, userId)
610+
}
611+
612+
func TestAllUserActiveSignatureAPI(t *testing.T) {
613+
allUserActiveSignatures := getAllPrimaryKeys("store", "key", "S")
614+
615+
var failed []string
616+
var mtx sync.Mutex
617+
sem := make(chan struct{}, MAX_PARALLEL)
618+
var wg sync.WaitGroup
619+
620+
for _, key := range allUserActiveSignatures {
621+
ky, ok := key.(string)
622+
if !ok {
623+
t.Errorf("Expected string key, got: %T", key)
624+
continue
625+
}
626+
if !strings.HasPrefix(ky, "active_signature:") {
627+
continue
628+
}
629+
userId := strings.TrimPrefix(ky, "active_signature:")
630+
631+
wg.Add(1)
632+
sem <- struct{}{}
633+
634+
go func(userId string) {
635+
defer wg.Done()
636+
defer func() { <-sem }()
637+
638+
t.Run(fmt.Sprintf("UserId=%s", userId), func(t *testing.T) {
639+
runUserActiveSignatureAPIForUser(t, userId)
640+
if t.Failed() {
641+
mtx.Lock()
642+
failed = append(failed, userId)
643+
mtx.Unlock()
644+
}
645+
})
646+
}(userId)
647+
}
648+
649+
wg.Wait()
650+
651+
if len(failed) > 0 {
652+
fmt.Fprintf(os.Stderr, "\nFailed User IDs (%d):\n%s\n\n",
653+
len(failed),
654+
strings.Join(failed, "\n"),
655+
)
656+
t.Fail()
657+
} else {
658+
fmt.Println("\nAll user active signatures passed.")
659+
}
660+
}

tests/py2go/dynamo.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,11 @@ func getAllPrimaryKeys(tableName, keyName, keyType string) []interface{} {
143143
for {
144144
input := &dynamodb.ScanInput{
145145
TableName: aws.String(tName),
146-
ProjectionExpression: aws.String(keyName),
147-
ExclusiveStartKey: lastEvaluatedKey,
146+
ProjectionExpression: aws.String("#k"),
147+
ExpressionAttributeNames: map[string]string{
148+
"#k": keyName,
149+
},
150+
ExclusiveStartKey: lastEvaluatedKey,
148151
}
149152

150153
output, err := client.Scan(context.TODO(), input)

0 commit comments

Comments
 (0)