Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: test management #240

Merged
merged 15 commits into from
Aug 23, 2022
2 changes: 1 addition & 1 deletion apis/data/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions apis/meta/v1alpha1/project_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func (r ProjectSubType) Validate(fld *field.Path) field.ErrorList {
MavenRepositoryProjectSubType: {},
RawRepositoryProjectSubType: {},
ProjectManagementSubtype: {},
TestProjectSubType: {},
}

if _, exist := supportedTypes[r]; !exist {
Expand Down Expand Up @@ -86,6 +87,9 @@ const (
// ProjectManagementSubtype project management subtype
ProjectManagementSubtype ProjectSubType = "ProjectManagement"

// TestProjectSubType test project subtype
TestProjectSubType ProjectSubType = "TestProject"

// TODO: add more subtypes
)

Expand Down
104 changes: 104 additions & 0 deletions apis/meta/v1alpha1/testcase_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
Copyright 2022 The Katanomi Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
authv1 "k8s.io/api/authorization/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var TestCaseGVK = GroupVersion.WithKind("TestCase")
var TestCaseListGVK = GroupVersion.WithKind("TestCaseList")

// TestCase object for plugins
type TestCase struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec TestCaseSpec `json:"spec"`

Status TestCaseStatus `json:"status,omitempty"`
}

// TestCaseSpec spec for TestCase
type TestCaseSpec struct {
// ID is the test plan id
ID string `json:"id"`
// Type is the type description from integration tools
Type string `json:"type"`
// Prerequisite are the preparations before executing the testcase steps
Prerequisite string `json:"prerequisite"`
// Steps tell testers how to do to execute this case
Steps []TestCaseStepInfo `json:"steps"`
// CreatedBy is the user who created the TestCase
// +optional
CreatedBy UserSpec `json:"createdBy"`
// Priority shows how important this case is
Priority string `json:"priority"`
// RelatedRequirements is a list of product requirements related to this test case
// +optional
RelatedRequirements []TestCaseRelatedObjectInfo `json:"relatedRequirements"`
// RelatedBugs is a list of bugs related to this test case
// +optional
RelatedBugs []TestCaseRelatedObjectInfo `json:"relatedBugs"`
}

// TestCaseStepInfo describes details of TestCaseStep
type TestCaseStepInfo struct {
// ID is the id of step generated by integration tools
ID string `json:"id"`
// Description shows how to run this step
Description string `json:"description"`
// Order shows the order of step
Order string `json:"order"`
// Expect shows the expected output after running this step
Expect string `json:"expect"`
}

// TestCaseRelatedObjectInfo refers to an object related to test case
type TestCaseRelatedObjectInfo struct {
kinsolee marked this conversation as resolved.
Show resolved Hide resolved
// Title is the title of related object
Title string `json:"title"`
// TargetURL is the URL for redirection
// +optional
TargetURL string `json:"targetURL"`
}

// TestCaseStatus includes status of test case
type TestCaseStatus struct {
// LastExecution is spec of the latest TestExecution related to the test case
// +optional
LastExecution *TestCaseExecutionSpec `json:"lastExecution"`
}

// TestCaseList list of TestCases
type TestCaseList struct {
metav1.TypeMeta `json:",inline"`
ListMeta `json:"metadata,omitempty"`

Items []TestCase `json:"items"`
}

// TestCaseResourceAttributes returns a ResourceAttribute object to be used in a filter
func TestCaseResourceAttributes(verb string) authv1.ResourceAttributes {
return authv1.ResourceAttributes{
Group: GroupVersion.Group,
Version: GroupVersion.Version,
Resource: "testcases",
Verb: verb,
}
}
36 changes: 36 additions & 0 deletions apis/meta/v1alpha1/testcase_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2022 The Katanomi Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
authv1 "k8s.io/api/authorization/v1"
)

var _ = Describe("TestCaseType", func() {
Context("TestCaseResourceAttributes", func() {
It("should return related attributes", func() {
Expect(TestCaseResourceAttributes("get")).To(Equal(authv1.ResourceAttributes{
Group: GroupVersion.Group,
Version: GroupVersion.Version,
Resource: "testcases",
Verb: "get",
}))
})
})
})
81 changes: 81 additions & 0 deletions apis/meta/v1alpha1/testcaseexecution_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
Copyright 2022 The Katanomi Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
authv1 "k8s.io/api/authorization/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var TestCaseExecutionGVK = GroupVersion.WithKind("TestCaseExecution")
var TestCaseExecutionListGVK = GroupVersion.WithKind("TestCaseExecutionList")

// TestCaseExecutionStatus covers possible values of TestcaseExecutionStatus
type TestCaseExecutionStatus string

// Possible test case execution status below
const (
TestcaseExecutionStatusPassed TestCaseExecutionStatus = "passed"
TestcaseExecutionStatusFailed TestCaseExecutionStatus = "failed"
TestcaseExecutionStatusBlocked TestCaseExecutionStatus = "blocked"
TestcaseExecutionStatusWaiting TestCaseExecutionStatus = "waiting"
)

// TestCaseExecution object for plugins
type TestCaseExecution struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec TestCaseExecutionSpec `json:"spec"`
}

// TestCaseExecutionSpec spec for TestCaseExecution
type TestCaseExecutionSpec struct {
// TestPlanID refers to the test plan including current test case
TestPlanID string `json:"testPlanId"`

// BuildRef refers to the build related to current test case
// +optional
BuildRef *TestObjectRef `json:"buildRef"`

// Status is the execution result status
Status TestCaseExecutionStatus `json:"status"`

// CreatedAt is the time when test case was executed
CreatedAt metav1.Time `json:"createdAt"`

// CreatedBy is the user who created the TestCaseExecution
CreatedBy UserSpec `json:"createdBy,omitempty"`
}

// TestCaseExecutionList list of TestCaseExecutions
type TestCaseExecutionList struct {
metav1.TypeMeta `json:",inline"`
ListMeta `json:"metadata,omitempty"`

Items []TestCaseExecution `json:"items"`
}

// TestCaseExecutionResourceAttributes returns a ResourceAttribute object to be used in a filter
func TestCaseExecutionResourceAttributes(verb string) authv1.ResourceAttributes {
return authv1.ResourceAttributes{
Group: GroupVersion.Group,
Version: GroupVersion.Version,
Resource: "testcaseexecutions",
Verb: verb,
}
}
36 changes: 36 additions & 0 deletions apis/meta/v1alpha1/testcaseexecution_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2022 The Katanomi Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
authv1 "k8s.io/api/authorization/v1"
)

var _ = Describe("TestCaseExecution", func() {
Context("TestCaseExecutionResourceAttributes", func() {
It("should return related attributes", func() {
Expect(TestCaseExecutionResourceAttributes("get")).To(Equal(authv1.ResourceAttributes{
Group: GroupVersion.Group,
Version: GroupVersion.Version,
Resource: "testcaseexecutions",
Verb: "get",
}))
})
})
})
85 changes: 85 additions & 0 deletions apis/meta/v1alpha1/testmodule_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
Copyright 2022 The Katanomi Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
authv1 "k8s.io/api/authorization/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var TestModuleGVK = GroupVersion.WithKind("TestModule")
var TestModuleListGVK = GroupVersion.WithKind("TestModuleList")

// TestModule object for plugins
type TestModule struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec TestModuleSpec `json:"spec"`
}

// TestModuleSpec spec for TestModule
type TestModuleSpec struct {
// ID is the test module id
ID string `json:"id"`
// Order is used to sort modules by ASC order
Order int `json:"order"`
// ParentID is the parent module ID
ParentID string `json:"parentID"`
// TestCases are the cases included by a module
// +optional
TestCases []TestModuleCaseRef `json:"testCases"`
}

// TestModuleCaseRef refers to a test module and its order
type TestModuleCaseRef struct {
// TestObjectRef refers to a test case
TestCase TestObjectRef `json:"ref"`
// Order indicates the ASC order of the object at same level
Order int `json:"order"`
}

// TestModuleList list of TestModules
type TestModuleList struct {
metav1.TypeMeta `json:",inline"`
ListMeta `json:"metadata,omitempty"`

Items []TestModule `json:"items"`
}

// TestModuleResourceAttributes returns a ResourceAttribute object to be used in a filter
func TestModuleResourceAttributes(verb string) authv1.ResourceAttributes {
return authv1.ResourceAttributes{
Group: GroupVersion.Group,
Version: GroupVersion.Version,
Resource: "testmodules",
Verb: verb,
}
}

func (tm *TestModule) ContainsTestCaseID(caseID string) bool {
if tm == nil || tm.Spec.TestCases == nil {
return false
}

for _, tc := range tm.Spec.TestCases {
if tc.TestCase.ID == caseID {
return true
}
}
return false
}
Loading