Skip to content

Commit

Permalink
Add resource update tests
Browse files Browse the repository at this point in the history
Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>
  • Loading branch information
helsaawy committed Dec 19, 2023
1 parent 2d896c5 commit 19df8c4
Show file tree
Hide file tree
Showing 14 changed files with 457 additions and 185 deletions.
3 changes: 2 additions & 1 deletion internal/memory/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import "github.com/pkg/errors"
type classType uint32

const (
MiB = 1024 * 1024
KiB = 1024
MiB = 1024 * KiB
GiB = 1024 * MiB
)

Expand Down
44 changes: 25 additions & 19 deletions internal/sync/once.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,38 @@ import (
// OnceValue is a wrapper around [sync.Once] that runs f only once and
// returns both a value (of type T) and an error.
func OnceValue[T any](f func() (T, error)) func() (T, error) {
var (
once sync.Once
v T
err error
)
once := &OnceErr[T]{}

return func() (T, error) {
once.Do(func() {
v, err = f()
})
return v, err
return once.Do(f)
}
}

// NewOnce is similar to [OnceValue], but allows passing a context to f.
func OnceValueCtx[T any](f func(ctx context.Context) (T, error)) func(context.Context) (T, error) {
var (
once sync.Once
v T
err error
)
func OnceValueCtx[T any](f func(context.Context) (T, error)) func(context.Context) (T, error) {
once := &OnceErr[T]{}

return func(ctx context.Context) (T, error) {
once.Do(func() {
v, err = f(ctx)
})
return v, err
return once.DoCtx(ctx, f)
}
}

type OnceErr[T any] struct {
once sync.Once
v T
err error
}

func (o *OnceErr[T]) Do(f func() (T, error)) (T, error) {
o.once.Do(func() {
o.v, o.err = f()
})
return o.v, o.err
}

func (o *OnceErr[T]) DoCtx(ctx context.Context, f func(context.Context) (T, error)) (T, error) {
o.once.Do(func() {
o.v, o.err = f(ctx)
})
return o.v, o.err
}
9 changes: 9 additions & 0 deletions internal/winapi/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,12 @@ package winapi

//sys LocalAlloc(flags uint32, size int) (ptr uintptr) = kernel32.LocalAlloc
//sys LocalFree(ptr uintptr) = kernel32.LocalFree

// BOOL GetPhysicallyInstalledSystemMemory(
// [out] PULONGLONG TotalMemoryInKilobytes
// );
//sys getPhysicallyInstalledSystemMemory(TotalMemoryInKilobytes *uint64) (err error)= kernel32.GetPhysicallyInstalledSystemMemory

func GetPhysicallyInstalledSystemMemory() (kb uint64, _ error) {
return kb, getPhysicallyInstalledSystemMemory(&kb)
}
9 changes: 9 additions & 0 deletions internal/winapi/zsyscall_windows.go

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

128 changes: 67 additions & 61 deletions test/functional/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ var allFeatures = []string{
}

var (
flagLogLevel = testflag.NewLogrusLevel("log-level", logrus.WarnLevel.String(), "logrus logging `level`")
flagLogLevel = testflag.NewLogrusLevel("log-level", logrus.WarnLevel.String(), "logrus logging `level`")

flagFeatures = testflag.NewFeatureFlag(allFeatures)
flagContainerdNamespace = flag.String("ctr-namespace", hcsOwner,
"containerd `namespace` to use when creating OCI specs")
Expand Down Expand Up @@ -173,81 +174,86 @@ func runTests(m *testing.M) error {
logrus.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
logrus.SetLevel(flagLogLevel.Level)

logrus.Debugf("using features: %s", flagFeatures.Strings())

if flagFeatures.IsSet(featureLCOWIntegrity) {
logrus.Info("appending verity information to LCOW images")
alpineImagePaths.AppendVerity = true
}
if !util.IsTestReExec() {
// don't bother re-setting up testing infra for a re-exec, since we really shouldn't
// be doing testing/uVM/image related things outside the main test

imgs := []*testlayers.LazyImageLayers{}
if flagFeatures.IsSet(featureLCOWIntegrity) || flagFeatures.IsSet(featureLCOW) {
imgs = append(imgs, alpineImagePaths)
}
logrus.Debugf("using features: %s", flagFeatures.Strings())

if flagFeatures.IsSet(featureWCOW) {
wcow, err := wcowImagePathsOnce()
if err != nil {
return err
if flagFeatures.IsSet(featureLCOWIntegrity) {
logrus.Info("appending verity information to LCOW images")
alpineImagePaths.AppendVerity = true
}

logrus.WithField("image", wcow.nanoserver.Image).Info("using Nano Server image")
logrus.WithField("image", wcow.nanoserver.Image).Info("using Server Core image")
imgs := []*testlayers.LazyImageLayers{}
if flagFeatures.IsSet(featureLCOWIntegrity) || flagFeatures.IsSet(featureLCOW) {
imgs = append(imgs, alpineImagePaths)
}

imgs = append(imgs, wcow.nanoserver, wcow.servercore)
}
if flagFeatures.IsSet(featureWCOW) {
wcow, err := wcowImagePathsOnce()
if err != nil {
return err
}

for _, l := range imgs {
l.TempPath = *flagLayerTempDir
}
logrus.WithField("image", wcow.nanoserver.Image).Info("using Nano Server image")
logrus.WithField("image", wcow.nanoserver.Image).Info("using Server Core image")

defer func(ctx context.Context) {
cleanupComputeSystems(ctx, hcsOwner)
imgs = append(imgs, wcow.nanoserver, wcow.servercore)
}

for _, l := range imgs {
if l == nil {
continue
}
// just log errors: no other cleanup possible
if err := l.Close(ctx); err != nil {
log.G(ctx).WithFields(logrus.Fields{
logrus.ErrorKey: err,
"image": l.Image,
"platform": l.Platform,
}).Warning("image cleanup failed")
}
l.TempPath = *flagLayerTempDir
}
}(ctx)

// print additional configuration options when running benchmarks, so we can track performance.
//
// also, print to ETW instead of stdout to mirror actual deployments, and to prevent logs from
// interfering with benchmarking output
if util.RunningBenchmarks() {
util.PrintAdditionalBenchmarkConfig()
// also print out the features used as part of the benchmarking config
fmt.Printf("features: %s\n", flagFeatures.Strings())

provider, err := etw.NewProviderWithOptions("Microsoft.Virtualization.RunHCS")
if err != nil {
logrus.Error(err)
} else {
if hook, err := etwlogrus.NewHookFromProvider(provider); err == nil {
logrus.AddHook(hook)
defer func(ctx context.Context) {
cleanupComputeSystems(ctx, hcsOwner)

for _, l := range imgs {
if l == nil {
continue
}
// just log errors: no other cleanup possible
if err := l.Close(ctx); err != nil {
log.G(ctx).WithFields(logrus.Fields{
logrus.ErrorKey: err,
"image": l.Image,
"platform": l.Platform,
}).Warning("image cleanup failed")
}
}
}(ctx)

// print additional configuration options when running benchmarks, so we can track performance.
//
// also, print to ETW instead of stdout to mirror actual deployments, and to prevent logs from
// interfering with benchmarking output
if util.RunningBenchmarks() {
util.PrintAdditionalBenchmarkConfig()
// also print out the features used as part of the benchmarking config
fmt.Printf("features: %s\n", flagFeatures.Strings())

provider, err := etw.NewProviderWithOptions("Microsoft.Virtualization.RunHCS")
if err != nil {
logrus.Error(err)
} else {
logrus.WithError(err).Error("could not create ETW logrus hook")
if hook, err := etwlogrus.NewHookFromProvider(provider); err == nil {
logrus.AddHook(hook)
} else {
logrus.WithError(err).Error("could not create ETW logrus hook")
}
}
}

// regardless of ETW provider status, still discard logs
logrus.SetFormatter(log.NopFormatter{})
logrus.SetOutput(io.Discard)
// regardless of ETW provider status, still discard logs
logrus.SetFormatter(log.NopFormatter{})
logrus.SetOutput(io.Discard)

defer func() {
// un-discard logs during cleanup
logrus.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
logrus.SetOutput(os.Stdout)
}()
defer func() {
// un-discard logs during cleanup
logrus.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
logrus.SetOutput(os.Stdout)
}()
}
}

if e := m.Run(); e != 0 {
Expand Down
73 changes: 0 additions & 73 deletions test/functional/uvm_memory_test.go

This file was deleted.

Loading

0 comments on commit 19df8c4

Please sign in to comment.