vitess.io/vitess@v0.16.2/go/vt/topo/test/directory.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package test
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"context"
    24  
    25  	"vitess.io/vitess/go/vt/topo"
    26  )
    27  
    28  // checkDirectory tests the directory part of the topo.Conn API.
    29  func checkDirectory(t *testing.T, ts *topo.Server) {
    30  	ctx := context.Background()
    31  
    32  	// global cell
    33  	t.Logf("===   checkDirectoryInCell global")
    34  	conn, err := ts.ConnForCell(ctx, topo.GlobalCell)
    35  	if err != nil {
    36  		t.Fatalf("ConnForCell(global) failed: %v", err)
    37  	}
    38  	checkDirectoryInCell(t, conn, true /*hasCells*/)
    39  
    40  	// local cell
    41  	t.Logf("===   checkDirectoryInCell test")
    42  	conn, err = ts.ConnForCell(ctx, LocalCellName)
    43  	if err != nil {
    44  		t.Fatalf("ConnForCell(test) failed: %v", err)
    45  	}
    46  	checkDirectoryInCell(t, conn, false /*hasCells*/)
    47  }
    48  
    49  func checkListDir(ctx context.Context, t *testing.T, conn topo.Conn, dirPath string, expected []topo.DirEntry) {
    50  	t.Helper()
    51  
    52  	// Build the shallow expected list, when full=false.
    53  	se := make([]topo.DirEntry, len(expected))
    54  	for i, e := range expected {
    55  		se[i].Name = e.Name
    56  	}
    57  
    58  	// Test with full=false.
    59  	entries, err := conn.ListDir(ctx, dirPath, false /*full*/)
    60  	switch {
    61  	case topo.IsErrType(err, topo.NoNode):
    62  		if len(se) != 0 {
    63  			t.Errorf("ListDir(%v, false) returned ErrNoNode but was expecting %v", dirPath, se)
    64  		}
    65  	case err == nil:
    66  		if len(se) != 0 || len(entries) != 0 {
    67  			if !reflect.DeepEqual(entries, se) {
    68  				t.Errorf("ListDir(%v, false) returned %v but was expecting %v", dirPath, entries, se)
    69  			}
    70  		}
    71  	default:
    72  		t.Errorf("ListDir(%v, false) returned unexpected error: %v", dirPath, err)
    73  	}
    74  
    75  	// Test with full=true.
    76  	entries, err = conn.ListDir(ctx, dirPath, true /*full*/)
    77  	switch {
    78  	case topo.IsErrType(err, topo.NoNode):
    79  		if len(expected) != 0 {
    80  			t.Errorf("ListDir(%v, true) returned ErrNoNode but was expecting %v", dirPath, expected)
    81  		}
    82  	case err == nil:
    83  		if len(expected) != 0 || len(entries) != 0 {
    84  			if !reflect.DeepEqual(entries, expected) {
    85  				t.Errorf("ListDir(%v, true) returned %v but was expecting %v", dirPath, entries, expected)
    86  			}
    87  		}
    88  	default:
    89  		t.Errorf("ListDir(%v, true) returned unexpected error: %v", dirPath, err)
    90  	}
    91  }
    92  
    93  func checkDirectoryInCell(t *testing.T, conn topo.Conn, hasCells bool) {
    94  	ctx := context.Background()
    95  
    96  	// ListDir root: nothing
    97  	var expected []topo.DirEntry
    98  	if hasCells {
    99  		expected = append(expected, topo.DirEntry{
   100  			Name: "cells",
   101  			Type: topo.TypeDirectory,
   102  		})
   103  	}
   104  	checkListDir(ctx, t, conn, "/", expected)
   105  
   106  	// Create a topolevel entry
   107  	version, err := conn.Create(ctx, "/MyFile", []byte{'a'})
   108  	if err != nil {
   109  		t.Fatalf("cannot create toplevel file: %v", err)
   110  	}
   111  
   112  	// ListDir should return it.
   113  	expected = append([]topo.DirEntry{
   114  		{
   115  			Name: "MyFile",
   116  			Type: topo.TypeFile,
   117  		},
   118  	}, expected...)
   119  	checkListDir(ctx, t, conn, "/", expected)
   120  
   121  	// Delete it, it should be gone.
   122  	if err := conn.Delete(ctx, "/MyFile", version); err != nil {
   123  		t.Fatalf("cannot delete toplevel file: %v", err)
   124  	}
   125  	expected = expected[1:]
   126  	checkListDir(ctx, t, conn, "/", expected)
   127  
   128  	// Create a file 3 layers down.
   129  	version, err = conn.Create(ctx, "/types/name/MyFile", []byte{'a'})
   130  	if err != nil {
   131  		t.Fatalf("cannot create deep file: %v", err)
   132  	}
   133  	expected = append(expected, topo.DirEntry{
   134  		Name: "types",
   135  		Type: topo.TypeDirectory,
   136  	})
   137  
   138  	// Check listing at all levels.
   139  	checkListDir(ctx, t, conn, "/", expected)
   140  	checkListDir(ctx, t, conn, "/types/", []topo.DirEntry{
   141  		{
   142  			Name: "name",
   143  			Type: topo.TypeDirectory,
   144  		},
   145  	})
   146  	checkListDir(ctx, t, conn, "/types/name/", []topo.DirEntry{
   147  		{
   148  			Name: "MyFile",
   149  			Type: topo.TypeFile,
   150  		},
   151  	})
   152  
   153  	// Add a second file
   154  	version2, err := conn.Create(ctx, "/types/othername/MyFile", []byte{'a'})
   155  	if err != nil {
   156  		t.Fatalf("cannot create deep file2: %v", err)
   157  	}
   158  
   159  	// Check entries at all levels
   160  	checkListDir(ctx, t, conn, "/", expected)
   161  	checkListDir(ctx, t, conn, "/types/", []topo.DirEntry{
   162  		{
   163  			Name: "name",
   164  			Type: topo.TypeDirectory,
   165  		},
   166  		{
   167  			Name: "othername",
   168  			Type: topo.TypeDirectory,
   169  		},
   170  	})
   171  	checkListDir(ctx, t, conn, "/types/name/", []topo.DirEntry{
   172  		{
   173  			Name: "MyFile",
   174  			Type: topo.TypeFile,
   175  		},
   176  	})
   177  	checkListDir(ctx, t, conn, "/types/othername/", []topo.DirEntry{
   178  		{
   179  			Name: "MyFile",
   180  			Type: topo.TypeFile,
   181  		},
   182  	})
   183  
   184  	// Delete the first file, expect all lists to return the second one.
   185  	if err := conn.Delete(ctx, "/types/name/MyFile", version); err != nil {
   186  		t.Fatalf("cannot delete deep file: %v", err)
   187  	}
   188  	checkListDir(ctx, t, conn, "/", expected)
   189  	checkListDir(ctx, t, conn, "/types/", []topo.DirEntry{
   190  		{
   191  			Name: "othername",
   192  			Type: topo.TypeDirectory,
   193  		},
   194  	})
   195  	checkListDir(ctx, t, conn, "/types/name/", nil)
   196  	checkListDir(ctx, t, conn, "/types/othername/", []topo.DirEntry{
   197  		{
   198  			Name: "MyFile",
   199  			Type: topo.TypeFile,
   200  		},
   201  	})
   202  
   203  	// Delete the second file, expect all lists to return nothing.
   204  	if err := conn.Delete(ctx, "/types/othername/MyFile", version2); err != nil {
   205  		t.Fatalf("cannot delete second deep file: %v", err)
   206  	}
   207  	for _, dir := range []string{"/types/", "/types/name/", "/types/othername/"} {
   208  		checkListDir(ctx, t, conn, dir, nil)
   209  	}
   210  	expected = expected[:len(expected)-1]
   211  	checkListDir(ctx, t, conn, "/", expected)
   212  }