Skip to content

FakeSnow

Not available until the next release main

Introduction

fakesnow is a Snowflake fake backed by DuckDB. It runs as an HTTP server speaking the Snowflake REST API, so the official gosnowflake driver connects to it unmodified and Snowflake-flavoured SQL such as VARIANT, LATERAL FLATTEN and QUALIFY works without a Snowflake account.

Adding this module to your project dependencies

Please run the following command to add the FakeSnow module to your Go dependencies:

go get github.com/testcontainers/testcontainers-go/modules/fakesnow

Usage example

ctx := context.Background()

fakesnowContainer, err := fakesnow.Run(ctx, "ghcr.io/tekumara/fakesnow:0.11.21")
defer func() {
    if err := testcontainers.TerminateContainer(fakesnowContainer); err != nil {
        log.Printf("failed to terminate container: %s", err)
    }
}()
if err != nil {
    log.Printf("failed to start container: %s", err)
    return
}

Connecting to it with database/sql:

ctx := context.Background()

fakesnowContainer, err := fakesnow.Run(ctx, "ghcr.io/tekumara/fakesnow:0.11.21")
defer func() {
    if err := testcontainers.TerminateContainer(fakesnowContainer); err != nil {
        log.Printf("failed to terminate container: %s", err)
    }
}()
if err != nil {
    log.Printf("failed to start container: %s", err)
    return
}

dsn, err := fakesnowContainer.ConnectionString(ctx)
if err != nil {
    log.Printf("failed to get connection string: %s", err)
    return
}

db, err := sql.Open("snowflake", dsn)
if err != nil {
    log.Printf("failed to open database: %s", err)
    return
}
defer db.Close()

// fakesnow starts empty, so create what the DSN points at.
if _, err := db.Exec("CREATE DATABASE IF NOT EXISTS db1"); err != nil {
    log.Printf("failed to create database: %s", err)
    return
}
if _, err := db.Exec("CREATE SCHEMA IF NOT EXISTS db1.schema1"); err != nil {
    log.Printf("failed to create schema: %s", err)
    return
}

var planet string
if err := db.QueryRow(`SELECT PARSE_JSON('{"planet":"saturn"}'):planet::varchar`).Scan(&planet); err != nil {
    log.Printf("failed to query: %s", err)
    return
}

fmt.Println(planet)

// Output:
// saturn

fakesnow starts with no databases, so create the one the DSN points at before using it.

Module Reference

Run function

  • Not available until the next release main

The FakeSnow module exposes one entrypoint function to create the FakeSnow container, and this function receives three parameters:

func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error)
  • context.Context, the Go context.
  • string, the Docker image to use.
  • testcontainers.ContainerCustomizer, a variadic argument for passing options.

Image

Use the second argument in the Run function to set a valid Docker image. In example: Run(context.Background(), "ghcr.io/tekumara/fakesnow:0.11.21").

Container Options

When starting the FakeSnow container, you can pass options in a variadic way to configure it.

The following options are exposed by the testcontainers package.

Basic Options

Lifecycle Options

Files & Mounts Options

Build Options

Logging Options

Image Options

Networking Options

Advanced Options

Experimental Options

Connection details

fakesnow accepts any credentials, so these options only change what the driver sends.

  • WithAccount(account string), the account, fakesnow by default. It cannot be empty: gosnowflake then derives the account from the host, which has no account part when the host is a container address.
  • WithUsername(user string), the user, fakesnow by default.
  • WithPassword(password string), the password, fakesnow by default.
  • WithDatabase(database string), the database in the DSN, db1 by default. It is not created for you.
  • WithSchema(schema string), the schema in the DSN, schema1 by default. It is not created for you.

Container Methods

The FakeSnow container exposes the following methods:

ConnectionString

  • Not available until the next release main

Returns a gosnowflake DSN for the container, for use with sql.Open("snowflake", dsn).

host, err := c.Host(ctx)
if err != nil {
    return "", fmt.Errorf("get host: %w", err)
}

port, err := c.MappedPort(ctx, defaultPort)
if err != nil {
    return "", fmt.Errorf("get mapped port: %w", err)
}

dsn, err := sf.DSN(&sf.Config{
    Account:  c.opts.account,
    User:     c.opts.user,
    Password: c.opts.password,
    Host:     host,
    Port:     int(port.Num()),
    Protocol: "http",
    Database: c.opts.database,
    Schema:   c.opts.schema,
})
if err != nil {
    return "", fmt.Errorf("build dsn: %w", err)
}

return dsn, nil