github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/objectstorage/v1/versioning_test.go (about)

     1  //go:build acceptance
     2  // +build acceptance
     3  
     4  package v1
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/gophercloud/gophercloud/internal/acceptance/clients"
    11  	"github.com/gophercloud/gophercloud/internal/acceptance/tools"
    12  	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers"
    13  	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects"
    14  	th "github.com/gophercloud/gophercloud/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(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(client, cName)
    43  		th.AssertNoErr(t, res.Err)
    44  	}()
    45  
    46  	// ensure versioning is enabled
    47  	get, err := containers.Get(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(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(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(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(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(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(client, cName, oNames[i], opts)
   105  			th.AssertNoErr(t, res.Err)
   106  		}
   107  	}()
   108  
   109  	// List created objects
   110  	listOpts := objects.ListOpts{
   111  		Full:   true,
   112  		Prefix: "test-object-",
   113  	}
   114  
   115  	allPages, err := objects.List(client, cName, listOpts).AllPages()
   116  	if err != nil {
   117  		t.Fatalf("Unable to list objects: %v", err)
   118  	}
   119  
   120  	ons, err := objects.ExtractNames(allPages)
   121  	if err != nil {
   122  		t.Fatalf("Unable to extract objects: %v", err)
   123  	}
   124  	th.AssertEquals(t, len(ons), len(oNames))
   125  
   126  	ois, err := objects.ExtractInfo(allPages)
   127  	if err != nil {
   128  		t.Fatalf("Unable to extract object info: %v", err)
   129  	}
   130  	th.AssertEquals(t, len(ois), len(oNames))
   131  
   132  	// List all created objects
   133  	listOpts = objects.ListOpts{
   134  		Full:     true,
   135  		Prefix:   "test-object-",
   136  		Versions: true,
   137  	}
   138  
   139  	allPages, err = objects.List(client, cName, listOpts).AllPages()
   140  	if err != nil {
   141  		t.Fatalf("Unable to list objects: %v", err)
   142  	}
   143  
   144  	ons, err = objects.ExtractNames(allPages)
   145  	if err != nil {
   146  		t.Fatalf("Unable to extract objects: %v", err)
   147  	}
   148  	th.AssertEquals(t, len(ons), 2*len(oNames))
   149  
   150  	ois, err = objects.ExtractInfo(allPages)
   151  	if err != nil {
   152  		t.Fatalf("Unable to extract object info: %v", err)
   153  	}
   154  	th.AssertEquals(t, len(ois), 2*len(oNames))
   155  
   156  	// ensure proper versioning attributes are set
   157  	for i, obj := range ois {
   158  		if i%2 == 0 {
   159  			th.AssertEquals(t, true, obj.IsLatest)
   160  		} else {
   161  			th.AssertEquals(t, false, obj.IsLatest)
   162  		}
   163  		if obj.VersionID == "" {
   164  			t.Fatalf("Unexpected empty version_id for the %s object", obj.Name)
   165  		}
   166  	}
   167  
   168  	// Download one of the objects that was created above.
   169  	downloadres := objects.Download(client, cName, oNames[0], nil)
   170  	th.AssertNoErr(t, downloadres.Err)
   171  
   172  	o1Content, err := downloadres.ExtractContent()
   173  	th.AssertNoErr(t, err)
   174  
   175  	// Compare the two object's contents to test that the copy worked.
   176  	th.AssertEquals(t, oNewContents[0], string(o1Content))
   177  
   178  	// Download the another object that was create above.
   179  	downloadOpts := objects.DownloadOpts{
   180  		Newest: true,
   181  	}
   182  	downloadres = objects.Download(client, cName, oNames[1], downloadOpts)
   183  	th.AssertNoErr(t, downloadres.Err)
   184  	o2Content, err := downloadres.ExtractContent()
   185  	th.AssertNoErr(t, err)
   186  
   187  	// Compare the two object's contents to test that the copy worked.
   188  	th.AssertEquals(t, oNewContents[1], string(o2Content))
   189  }