Code Monkey home page Code Monkey logo

namspill's Introduction

namspill

PkgGoDev GitHub Go Report Card Coverage

ℹ️ If you don't switch Linux-kernel namespaces and don't use a Go module that does, you most probably don't need to fret about namspill.

In the spirit of leak tests for goroutines and file descriptors, namspill tests for Linux kernel namespaces unintendedly "leaking" between goroutines due to incorrect OS thread locking (or rather, the lack thereof) when switching namespaces in a Go program.

namspill is primarily designed to integrate smoothly with the Ginkgo BDD testing framework and the Gomega matcher/assertion library. (It may be used also outside Ginkgo/Gomega, but such usage is out of scope.)

Install

go get github.com/thediveo/namspill

Usage

In its simplest form, just after each test gather information about the namespaces of the tasks (threads) of the program and check that no namespaces have leaked, with some tasks being attached to other namespaces than the rest of the tasks.

As namspill exports only very few symbols and is intended to extend the Gomega DSL, you might want to dot-import it.

import . "github.com/thediveo/namspill"

AfterEach(func() {
    // You might want to use Eventually(Tasks)... in case you don't
    // have a preceeding Eventually(Goroutines)... that waits for
    // the Goroutines (and thus Linux threads/tasks) to settle first.
    Expect(Tasks()).To(BeUniformlyNamespaced())
})

Normally, you shouldn't then see anything unless there is a problem with threads attached to other Linux-kernel namespaces when they shouldn't. In this case, the BeUniformlyNamespaced matcher will fail and show you the list of tasks with the namespaces they're attached to.

Unfortunately, there's no way to show you which goroutine might have caused this nor the call site (and more importantly, the call stack) where the namespace switch happened.

Background

namspill mostly serves as a canary to (quickly) detect forgetting to switch back namespaces before unlocking OS threads so that they can be freely scheduled to any arbitrary goroutine.

The Initial Thread M0 Is Special

Additionally, namespill checks safeguard against alternatively not terminating thread-locked goroutines. And that is where there's a catch when it comes to the Go scheduler: if a Go program's initial thread ("M0" in Go scheduler parlance) ends up being locked to a (non-main) goroutine and this goroutine exits ... then the initial thread doesn't get terminated, because that usually has unwanted side-effects on several operating systems. Instead, the Go scheduler "wedges" the initial thread and never schedules any goroutine to it again.

This situation will (correctly) trigger failed namspill assertions. To avoid the initial thread getting wedged, simply lock it in an init function to the initial/main goroutine, so it never ends up getting scheduled on any other goroutine (that might be subjected to locking it to a thread and then terminating it while being locked):

func init() {
    runtime.LockOSThread()
}

References

For further background information, please see the following references:

Make Targets

  • make: lists all targets.
  • make coverage: runs all tests with coverage and then updates the coverage badge in README.md.
  • make pkgsite: installs x/pkgsite, as well as the browser-sync and nodemon npm packages first, if not already done so. Then runs the pkgsite and hot reloads it whenever the documentation changes.
  • make report: installs @gojp/goreportcard if not yet done so and then runs it on the code base.
  • make test: runs all tests.

Copyright and License

namspill is Copyright 2022, 2022 Harald Albrecht, and licensed under the Apache License, Version 2.0.

namspill's People

Contributors

thediveo avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.