github.com/sacloud/iaas-api-go@v1.12.0/testutil/resource.go (about)

     1  // Copyright 2022-2023 The sacloud/iaas-api-go Authors
     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 testutil
    16  
    17  import (
    18  	"context"
    19  	"runtime/debug"
    20  	"time"
    21  
    22  	"github.com/sacloud/iaas-api-go"
    23  )
    24  
    25  type ResourceTestCase struct {
    26  	// PreCheck テスト実行 or スキップを判定するためのFunc
    27  	PreCheck func(TestT)
    28  
    29  	// APICallerのセットアップ用Func、テストケースごとに1回呼ばれる
    30  	SetupAPICallerFunc func() iaas.APICaller
    31  
    32  	// Setup テスト前の準備(依存リソースの作成など)を行うためのFunc(省略可)
    33  	Setup func(context.Context, iaas.APICaller) error
    34  
    35  	Tests []ResourceTestFunc
    36  
    37  	// Cleanup APIで作成/変更したリソースなどのクリーンアップ用Func(省略化)
    38  	Cleanup func(context.Context, iaas.APICaller) error
    39  
    40  	// Parallel t.Parallelを呼ぶかのフラグ
    41  	Parallel bool
    42  
    43  	Timeout time.Duration
    44  }
    45  
    46  type ResourceTestFunc func(ctx context.Context, caller iaas.APICaller) error
    47  
    48  func RunResource(t TestT, testCase *ResourceTestCase) {
    49  	if testCase.SetupAPICallerFunc == nil {
    50  		t.Fatal("CRUDTestCase.SetupAPICallerFunc is required")
    51  	}
    52  
    53  	if testCase.Parallel {
    54  		t.Parallel()
    55  	}
    56  
    57  	if testCase.PreCheck != nil {
    58  		testCase.PreCheck(t)
    59  	}
    60  
    61  	ctx := context.Background()
    62  	if testCase.Timeout > 0 {
    63  		withTimeout, cancel := context.WithTimeout(ctx, testCase.Timeout)
    64  		defer cancel()
    65  		ctx = withTimeout
    66  	}
    67  
    68  	defer func() {
    69  		// Cleanup
    70  		if testCase.Cleanup != nil {
    71  			if err := testCase.Cleanup(ctx, testCase.SetupAPICallerFunc()); err != nil {
    72  				t.Logf("cleanup failed: ", err)
    73  			}
    74  		}
    75  		if err := recover(); err != nil {
    76  			t.Logf("unexpected error has happen: %v, trace: %s", err, string(debug.Stack()))
    77  		}
    78  	}()
    79  
    80  	if testCase.Setup != nil {
    81  		if err := testCase.Setup(ctx, testCase.SetupAPICallerFunc()); err != nil {
    82  			t.Error("setup failed: ", err)
    83  			return
    84  		}
    85  	}
    86  
    87  	for _, testFunc := range testCase.Tests {
    88  		if err := testFunc(ctx, testCase.SetupAPICallerFunc()); err != nil {
    89  			t.Error("test func returns error: ", err)
    90  			return
    91  		}
    92  	}
    93  }