github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/objectstorage/v1/versioning_test.go (about)

     1  //go:build acceptance || objectstorage || versioning
     2  
     3  package v1
     4  
     5  import (
     6  	"context"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/clients"
    11  	"github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools"
    12  	"github.com/vnpaycloud-console/gophercloud/v2/openstack/objectstorage/v1/containers"
    13  	"github.com/vnpaycloud-console/gophercloud/v2/openstack/objectstorage/v1/objects"
    14  	th "github.com/vnpaycloud-console/gophercloud/v2/testhelper"
    15  )
    16  
    17  func TestObjectsVersioning(t *testing.T) {
    18  	clients.SkipReleasesBelow(t, "stable/ussuri")
    19  
    20  	client, err := clients.NewObjectStorageV1Client()
    21  	if err != nil {
    22  		t.Fatalf("Unable to create client: %v", err)
    23  	}
    24  
    25  	// Make a slice of length numObjects to hold the random object names.
    26  	oNames := make([]string, numObjects)
    27  	for i := 0; i < len(oNames); i++ {
    28  		oNames[i] = tools.RandomString("test-object-", 8)
    29  	}
    30  
    31  	// Create a container to hold the test objects.
    32  	cName := tools.RandomString("test-container-", 8)
    33  	opts := containers.CreateOpts{
    34  		VersionsEnabled: true,
    35  	}
    36  	header, err := containers.Create(context.TODO(), client, cName, opts).Extract()
    37  	th.AssertNoErr(t, err)
    38  	t.Logf("Create container headers: %+v\n", header)
    39  
    40  	// Defer deletion of the container until after testing.
    41  	defer func() {
    42  		res := containers.Delete(context.TODO(), client, cName)
    43  		th.AssertNoErr(t, res.Err)
    44  	}()
    45  
    46  	// ensure versioning is enabled
    47  	get, err := containers.Get(context.TODO(), client, cName, nil).Extract()
    48  	th.AssertNoErr(t, err)
    49  	t.Logf("Get container headers: %+v\n", get)
    50  	th.AssertEquals(t, true, get.VersionsEnabled)
    51  
    52  	// Create a slice of buffers to hold the test object content.
    53  	oContents := make([]string, numObjects)
    54  	oContentVersionIDs := make([]string, numObjects)
    55  	for i := 0; i < numObjects; i++ {
    56  		oContents[i] = tools.RandomString("", 10)
    57  		createOpts := objects.CreateOpts{
    58  			Content: strings.NewReader(oContents[i]),
    59  		}
    60  		obj, err := objects.Create(context.TODO(), client, cName, oNames[i], createOpts).Extract()
    61  		th.AssertNoErr(t, err)
    62  		oContentVersionIDs[i] = obj.ObjectVersionID
    63  	}
    64  	oNewContents := make([]string, numObjects)
    65  	for i := 0; i < numObjects; i++ {
    66  		oNewContents[i] = tools.RandomString("", 10)
    67  		createOpts := objects.CreateOpts{
    68  			Content: strings.NewReader(oNewContents[i]),
    69  		}
    70  		_, err := objects.Create(context.TODO(), client, cName, oNames[i], createOpts).Extract()
    71  		th.AssertNoErr(t, err)
    72  	}
    73  	// Delete the objects after testing two times.
    74  	defer func() {
    75  		// disable object versioning
    76  		opts := containers.UpdateOpts{
    77  			VersionsEnabled: new(bool),
    78  		}
    79  		header, err := containers.Update(context.TODO(), client, cName, opts).Extract()
    80  		th.AssertNoErr(t, err)
    81  
    82  		t.Logf("Update container headers: %+v\n", header)
    83  
    84  		// ensure versioning is disabled
    85  		get, err := containers.Get(context.TODO(), client, cName, nil).Extract()
    86  		th.AssertNoErr(t, err)
    87  		t.Logf("Get container headers: %+v\n", get)
    88  		th.AssertEquals(t, false, get.VersionsEnabled)
    89  
    90  		// delete all object versions before deleting the container
    91  		currentVersionIDs := make([]string, numObjects)
    92  		for i := 0; i < numObjects; i++ {
    93  			opts := objects.DeleteOpts{
    94  				ObjectVersionID: oContentVersionIDs[i],
    95  			}
    96  			obj, err := objects.Delete(context.TODO(), client, cName, oNames[i], opts).Extract()
    97  			th.AssertNoErr(t, err)
    98  			currentVersionIDs[i] = obj.ObjectCurrentVersionID
    99  		}
   100  		for i := 0; i < numObjects; i++ {
   101  			opts := objects.DeleteOpts{
   102  				ObjectVersionID: currentVersionIDs[i],
   103  			}
   104  			res := objects.Delete(context.TODO(), client, cName, oNames[i], opts)
   105  			th.AssertNoErr(t, res.Err)
   106  		}
   107  	}()
   108  
   109  	// List created objects
   110  	listOpts := objects.ListOpts{
   111  		Prefix: "test-object-",
   112  	}
   113  
   114  	allPages, err := objects.List(client, cName, listOpts).AllPages(context.TODO())
   115  	if err != nil {
   116  		t.Fatalf("Unable to list objects: %v", err)
   117  	}
   118  
   119  	ons, err := objects.ExtractNames(allPages)
   120  	if err != nil {
   121  		t.Fatalf("Unable to extract objects: %v", err)
   122  	}
   123  	th.AssertEquals(t, len(ons), len(oNames))
   124  
   125  	ois, err := objects.ExtractInfo(allPages)
   126  	if err != nil {
   127  		t.Fatalf("Unable to extract object info: %v", err)
   128  	}
   129  	th.AssertEquals(t, len(ois), len(oNames))
   130  
   131  	// List all created objects
   132  	listOpts = objects.ListOpts{
   133  		Prefix:   "test-object-",
   134  		Versions: true,
   135  	}
   136  
   137  	allPages, err = objects.List(client, cName, listOpts).AllPages(context.TODO())
   138  	if err != nil {
   139  		t.Fatalf("Unable to list objects: %v", err)
   140  	}
   141  
   142  	ons, err = objects.ExtractNames(allPages)
   143  	if err != nil {
   144  		t.Fatalf("Unable to extract objects: %v", err)
   145  	}
   146  	th.AssertEquals(t, len(ons), 2*len(oNames))
   147  
   148  	ois, err = objects.ExtractInfo(allPages)
   149  	if err != nil {
   150  		t.Fatalf("Unable to extract object info: %v", err)
   151  	}
   152  	th.AssertEquals(t, len(ois), 2*len(oNames))
   153  
   154  	// ensure proper versioning attributes are set
   155  	for i, obj := range ois {
   156  		if i%2 == 0 {
   157  			th.AssertEquals(t, true, obj.IsLatest)
   158  		} else {
   159  			th.AssertEquals(t, false, obj.IsLatest)
   160  		}
   161  		if obj.VersionID == "" {
   162  			t.Fatalf("Unexpected empty version_id for the %s object", obj.Name)
   163  		}
   164  	}
   165  
   166  	// Download one of the objects that was created above.
   167  	downloadres := objects.Download(context.TODO(), client, cName, oNames[0], nil)
   168  	th.AssertNoErr(t, downloadres.Err)
   169  
   170  	o1Content, err := downloadres.ExtractContent()
   171  	th.AssertNoErr(t, err)
   172  
   173  	// Compare the two object's contents to test that the copy worked.
   174  	th.AssertEquals(t, oNewContents[0], string(o1Content))
   175  
   176  	// Download the another object that was create above.
   177  	downloadOpts := objects.DownloadOpts{
   178  		Newest: true,
   179  	}
   180  	downloadres = objects.Download(context.TODO(), client, cName, oNames[1], downloadOpts)
   181  	th.AssertNoErr(t, downloadres.Err)
   182  	o2Content, err := downloadres.ExtractContent()
   183  	th.AssertNoErr(t, err)
   184  
   185  	// Compare the two object's contents to test that the copy worked.
   186  	th.AssertEquals(t, oNewContents[1], string(o2Content))
   187  }