Package virtuakube sets up virtual Kubernetes clusters for tests. The top-level object is a Universe. Everything else exists within a Universe, and is cleaned up when the Universe is closed. Within a Universe, you can create either bare VMs (using universe.NewVM), or Kubernetes clusters (using universe.NewCluster). A universe requires a directory on disk to store its state. You get a universe either by calling Create to make a new blank one, or by calling Open to reuse an existing one. There are three ways of closing a universe. Calling Destroy wipes all the universe's state. Save snapshots and preserve all current resources, such that the next call to Open will resume the universe exactly as it was when last saved. Close preserves the universe, but rewinds its state to the last time it was saved, or to its pristine post-creation state if it was never saved. A typical use of virtuakube in tests is to do expensive setup ahead of time: use Create to make a new universe, then create and configure resources within, and finally call Save to snapshot it. Then, tests can simply Open this universe to get a fully working system immediately. When each test is done, they can Close the universe to undo all the changes that happened during the test, ready for the next test to Open. VMs have a preset form that can be customized somewhat, but not fundamentally changed. Each VM has a single virtual disk, which is a copy-on-write fork of a base image. You can build base images with universe.NewImage. Each VM gets two network interfaces. The first provides internet access, and the second connects to a virtual LAN shared by all VMs in the same Universe. Network access to VMs from the host machine is only possible via port forwards, which are specified in the VM's configuration at creation time. Use vm.ForwardedPort to find out the local port to use to reach a given port on the VM. The VM type provides some helpers for running commands and reading/writing files on the VM. Clusters consist of one control plane VM, and a configurable number of additional worker VMs. Once created, the Cluster type has helpers to retrieve a kubeconfig file to talk to the cluster, a Go kubernetes client connected to the cluster, and the port to talk to the in-cluster registry to push images. VM images belong to a universe, and can be created with NewImage. NewImage accepts customization functions to do things like install extra packages, or configure services that all VMs using the image will need. If you customize your own VM image, it must conform to the following conventions for virtuakube to function correctly. The VM should autoconfigure the first network interface (ens3) using DHCP. Other ens* network interfaces should be left unconfigured. The `ip` tool must be installed so that virtuakube can configure those other interfaces. The VM should disable any kind of time synchronization, and rely purely on the VM's local virtual clock. VMs may spend hours or more suspended, and to avoid issues associated with timejumps on resume, virtuakube wants to maintain the illusion that no time has passed since suspend. If you want to use NewCluster with your VM image, the VM must have docker, kubectl and kubeadm preinstalled. Dependencies and prerequisites must be satisfied such that `kubeadm init` produces a working single-node cluster. Virtuakube includes stock customization functions to install Kubernetes prerequisites, and to pre-pull the Docker images for faster cluster startup when NewCluster is called.
Package clock is a near drop-in replacement for time.Now().UTC() and time.Sleep(). The structs defined here are intended to be used as pointer fields on struct types. When nil, these references forward to the corresponding functions in the standard time package. When not nil they perform behavior that facilitates unit testing when accessing the current time or sleeping is involved. The main advantage to this approach is that it is not necessary to provide a non-nil instance in 'contructor' functions or wireup for production code. It is also still trivial to set a non-nil reference in test code.
Package monoton is a highly scalable, single/multi node, human-readable, predictable and incremental unique id generator The monoton package provides sequences based on the monotonic time which represents the absolute elapsed wall-clock time since some arbitrary, fixed point in the past. It isn't affected by changes in the system time-of-day clock. Initial time value opens space for the time value by subtracting the given value from the time sequence. The monoton package converts all sequences into Base62 format. And Base62 only uses ASCII alpha-numeric chars to represent data which makes it easy to read, predict the order by a human eye. The total byte size is fixed to 16 bytes for all sequencers. And at least one byte is reserved to nodes. The monoton package can be used on single/multiple nodes without the need for machine coordination. It uses configured node identifier to generate ids by attaching the node identifier to the end of the sequences. The package comes with three pre-configured sequencers and Sequencer interface to allow new sequencers. The monoton package currently comes with Nanosecond, Millisecond and Second sequencers. And it uses Millisecond sequencer by default. For each sequencer, the byte orders are as following: The sequencers can be extended for any other time format, sequence format by implementing the monoton/sequncer.Sequencer interface. Example using Singleton
Package clocks provides the Clock interface and a default implementations: the defaultClock implementation (returned by DefaultClock()) defaultClock should always be used within production, as it is a trivial wrapper around the real clock-derived functions in the time package of the Go standard library. In the fake subpackage there is a fake.Clock (created by fake.NewClock()) fake.Clock is present for use in tests, with some helpers for useful synchronization, such as AwaitSleepers() which lets a test goroutine block until some number of other goroutines are sleeping. See the documentation on the individual methods of fake.Clock for more specific documentation. The offset subpackage contains an offset.Clock type which simply adds a constant offset to any interactions with an absolute time. This type is most useful for simulating clock-skew/unsynchronization in combination with the fake-clock.