<commit_before>// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package files

import (
	"github.com/coreos/ignition/v2/tests/register"
	"github.com/coreos/ignition/v2/tests/types"
)

func init() {
	register.Register(register.PositiveTest, CreateHardLinkOnRoot())
	register.Register(register.PositiveTest, MatchHardLinkOnRoot())
	register.Register(register.PositiveTest, CreateSymlinkOnRoot())
	register.Register(register.PositiveTest, MatchSymlinkOnRoot())
	register.Register(register.PositiveTest, ForceLinkCreation())
	register.Register(register.PositiveTest, ForceHardLinkCreation())
	register.Register(register.PositiveTest, WriteOverSymlink())
	register.Register(register.PositiveTest, WriteOverBrokenSymlink())
	register.Register(register.PositiveTest, CreateHardLinkToSymlink())
}

func CreateHardLinkOnRoot() types.Test {
	name := "links.hard.create"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/target",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/bar",
		  "target": "/foo/target",
		  "hard": true
	    }]
	  }
	}`
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "target",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Target: "/foo/target",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func MatchHardLinkOnRoot() types.Test {
	name := "links.hard.match"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/existing",
	      "target": "/target",
	      "hard": true
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
			Hard:   true,
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func CreateSymlinkOnRoot() types.Test {
	name := "links.sym.create"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/foo/bar",
	      "target": "/foo/target",
	      "hard": false
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "target",
				Directory: "foo",
			},
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Name:      "bar",
				Directory: "foo",
			},
			Target: "/foo/target",
			Hard:   false,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func MatchSymlinkOnRoot() types.Test {
	name := "links.sym.match"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/existing",
	      "target": "/target"
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func ForceLinkCreation() types.Test {
	name := "links.sym.create.force"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/target",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/bar",
	      "target": "/foo/target",
	      "overwrite": true
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "target",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Target: "/foo/target",
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func ForceHardLinkCreation() types.Test {
	name := "links.hard.create.force"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/target",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/bar",
	      "target": "/foo/target",
		  "hard": true,
	      "overwrite": true
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "target",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Target: "/foo/target",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func WriteOverSymlink() types.Test {
	name := "links.sym.writeover"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/etc/file",
	      "mode": 420,
	      "overwrite": true,
	      "contents": { "source": "" }
	    }]
	  }
	}`
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Target: "/usr/rofile",
		},
	})
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "rofile",
				Directory: "usr",
			},
			Contents: "",
			Mode:     420,
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "rofile",
				Directory: "usr",
			},
			Contents: "",
			Mode:     420,
		},
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Contents: "",
			Mode:     420,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func WriteOverBrokenSymlink() types.Test {
	name := "links.sym.writeover.broken"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/etc/file",
	      "mode": 420,
	      "overwrite": true,
	      "contents": { "source": "" }
	    }]
	  }
	}`
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Target: "/usr/rofile",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Contents: "",
			Mode:     420,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func CreateHardLinkToSymlink() types.Test {
	name := "links.hard.create.tosym"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/foo",
	      "target": "/bar",
	      "hard": true
	    }]
	  }
	}`
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "bar",
			},
			Target: "nonexistent",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "bar",
			},
			Target: "nonexistent",
		},
		{
			Node: types.Node{
				Directory: "/",
				Name:      "foo",
			},
			Target: "/bar",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}
<commit_msg>tests: add test for creating a deeper hard link to the file<commit_after>// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package files

import (
	"github.com/coreos/ignition/v2/tests/register"
	"github.com/coreos/ignition/v2/tests/types"
)

func init() {
	register.Register(register.PositiveTest, CreateHardLinkOnRoot())
	register.Register(register.PositiveTest, MatchHardLinkOnRoot())
	register.Register(register.PositiveTest, CreateSymlinkOnRoot())
	register.Register(register.PositiveTest, MatchSymlinkOnRoot())
	register.Register(register.PositiveTest, ForceLinkCreation())
	register.Register(register.PositiveTest, ForceHardLinkCreation())
	register.Register(register.PositiveTest, CreateDeepHardLinkToFile())
	register.Register(register.PositiveTest, WriteOverSymlink())
	register.Register(register.PositiveTest, WriteOverBrokenSymlink())
	register.Register(register.PositiveTest, CreateHardLinkToSymlink())
}

func CreateHardLinkOnRoot() types.Test {
	name := "links.hard.create"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/target",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/bar",
		  "target": "/foo/target",
		  "hard": true
	    }]
	  }
	}`
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "target",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Target: "/foo/target",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func MatchHardLinkOnRoot() types.Test {
	name := "links.hard.match"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/existing",
	      "target": "/target",
	      "hard": true
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
			Hard:   true,
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func CreateSymlinkOnRoot() types.Test {
	name := "links.sym.create"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/foo/bar",
	      "target": "/foo/target",
	      "hard": false
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "target",
				Directory: "foo",
			},
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Name:      "bar",
				Directory: "foo",
			},
			Target: "/foo/target",
			Hard:   false,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func MatchSymlinkOnRoot() types.Test {
	name := "links.sym.match"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/existing",
	      "target": "/target"
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "target",
			},
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "existing",
			},
			Target: "/target",
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func ForceLinkCreation() types.Test {
	name := "links.sym.create.force"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/target",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/bar",
	      "target": "/foo/target",
	      "overwrite": true
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "target",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Target: "/foo/target",
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func ForceHardLinkCreation() types.Test {
	name := "links.hard.create.force"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/target",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/bar",
	      "target": "/foo/target",
	      "hard": true,
	      "overwrite": true
	    }]
	  }
	}`
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "target",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "bar",
			},
			Target: "/foo/target",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

// CreateDeepHardLinkToFile checks if Ignition can create a hard
// link to a file that's deeper than the hard link. For more
// information: https://github.com/coreos/ignition/issues/800
func CreateDeepHardLinkToFile() types.Test {
	name := "links.hard.deep.create.file"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/foo/bar/baz",
	      "contents": {
	        "source": "http://127.0.0.1:8080/contents"
	      }
	    }],
	    "links": [{
	      "path": "/foo/quux",
	      "target": "/foo/bar/baz",
	      "hard": true
	    }]
	  }
	}`
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Directory: "foo/bar",
				Name:      "baz",
			},
			Contents: "asdf\nfdsa",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "foo",
				Name:      "quux",
			},
			Target: "/foo/bar/baz",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func WriteOverSymlink() types.Test {
	name := "links.sym.writeover"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/etc/file",
	      "mode": 420,
	      "overwrite": true,
	      "contents": { "source": "" }
	    }]
	  }
	}`
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Target: "/usr/rofile",
		},
	})
	in[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "rofile",
				Directory: "usr",
			},
			Contents: "",
			Mode:     420,
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "rofile",
				Directory: "usr",
			},
			Contents: "",
			Mode:     420,
		},
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Contents: "",
			Mode:     420,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func WriteOverBrokenSymlink() types.Test {
	name := "links.sym.writeover.broken"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "files": [{
	      "path": "/etc/file",
	      "mode": 420,
	      "overwrite": true,
	      "contents": { "source": "" }
	    }]
	  }
	}`
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Target: "/usr/rofile",
		},
	})
	out[0].Partitions.AddFiles("ROOT", []types.File{
		{
			Node: types.Node{
				Name:      "file",
				Directory: "etc",
			},
			Contents: "",
			Mode:     420,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}

func CreateHardLinkToSymlink() types.Test {
	name := "links.hard.create.tosym"
	in := types.GetBaseDisk()
	out := types.GetBaseDisk()
	config := `{
	  "ignition": { "version": "$version" },
	  "storage": {
	    "links": [{
	      "path": "/foo",
	      "target": "/bar",
	      "hard": true
	    }]
	  }
	}`
	in[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "bar",
			},
			Target: "nonexistent",
		},
	})
	out[0].Partitions.AddLinks("ROOT", []types.Link{
		{
			Node: types.Node{
				Directory: "/",
				Name:      "bar",
			},
			Target: "nonexistent",
		},
		{
			Node: types.Node{
				Directory: "/",
				Name:      "foo",
			},
			Target: "/bar",
			Hard:   true,
		},
	})
	configMinVersion := "3.0.0"

	return types.Test{
		Name:             name,
		In:               in,
		Out:              out,
		Config:           config,
		ConfigMinVersion: configMinVersion,
	}
}
<|endoftext|>


<commit_before>package box

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type CommentCollection struct {
	TotalCount int        `json:"total_count"`
	Entries    []*Comment `json:"entries"`
}

type Comment struct {
	Type           string `json:"type"`
	Id             string `json:"id"`
	IsReplyComment bool   `json:"is_reply_comment"`
	Message        string `json:"message"`
	CreatedBy      *Item  `json:"created_by"` // TODO(ttacon): change this to user, this needs to be a mini-user struct
	Item           *Item  `json:"item"`
	CreatedAt      string `json:"created_at"`  // TODO(ttacon): change to time.Time
	ModifiedAt     string `json:"modified_at"` // TODO(ttacon): change to time.Time
}

// Documentation: https://developers.box.com/docs/#comments-add-a-comment-to-an-item
func (c *Client) AddComment(itemType, id, message, taggedMessage string) (*http.Response, *Comment, error) {
	var dataMap = map[string]interface{}{
		"item": map[string]string{
			"type": itemType,
			"id":   id,
		},
		"message":        message,
		"tagged_message": taggedMessage,
	}
	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := http.NewRequest(
		"POST",
		fmt.Sprintf("%s/comments", BASE_URL),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data Comment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}
<commit_msg>Add ChangeCommentsMessage<commit_after>package box

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type CommentCollection struct {
	TotalCount int        `json:"total_count"`
	Entries    []*Comment `json:"entries"`
}

type Comment struct {
	Type           string `json:"type"`
	Id             string `json:"id"`
	IsReplyComment bool   `json:"is_reply_comment"`
	Message        string `json:"message"`
	CreatedBy      *Item  `json:"created_by"` // TODO(ttacon): change this to user, this needs to be a mini-user struct
	Item           *Item  `json:"item"`
	CreatedAt      string `json:"created_at"`  // TODO(ttacon): change to time.Time
	ModifiedAt     string `json:"modified_at"` // TODO(ttacon): change to time.Time
}

// Documentation: https://developers.box.com/docs/#comments-add-a-comment-to-an-item
func (c *Client) AddComment(itemType, id, message, taggedMessage string) (*http.Response, *Comment, error) {
	var dataMap = map[string]interface{}{
		"item": map[string]string{
			"type": itemType,
			"id":   id,
		},
		"message":        message,
		"tagged_message": taggedMessage,
	}
	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := http.NewRequest(
		"POST",
		fmt.Sprintf("%s/comments", BASE_URL),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data Comment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}

// Documentation: https://developers.box.com/docs/#comments-change-a-comments-message
func (c *Client) ChangeCommentsMessage(commendId, message string) (*http.Response, *Comment, error) {
	var dataMap = map[string]string{
		"message": message,
	}
	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, nil, err
	}

	req, err := htt.NewRequest(
		"PUT",
		fmt.Sprintf("%s/comments/%s", BASE_URL, commendId),
		bytes.NewReader(dataBytes),
	)
	if err != nil {
		return nil, nil, err
	}

	resp, err := c.Trans.Client().Do(req)
	if err != nil {
		return resp, nil, err
	}

	var data Comment
	err = json.NewDecoder(resp.Body).Decode(&data)
	return resp, &data, err
}
<|endoftext|>


<commit_before>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package timeout

import (
	"time"

	"github.com/ava-labs/avalanchego/ids"
	"github.com/ava-labs/avalanchego/snow/networking/benchlist"
	"github.com/ava-labs/avalanchego/utils/hashing"
	"github.com/ava-labs/avalanchego/utils/timer"
	"github.com/ava-labs/avalanchego/utils/wrappers"
)

// Manager registers and fires timeouts for the snow API.
type Manager struct {
	tm        timer.AdaptiveTimeoutManager
	benchlist benchlist.Manager
}

// Initialize this timeout manager.
func (m *Manager) Initialize(timeoutConfig *timer.AdaptiveTimeoutConfig, benchlist benchlist.Manager) error {
	m.benchlist = benchlist
	return m.tm.Initialize(timeoutConfig)
}

// Dispatch ...
func (m *Manager) Dispatch() { m.tm.Dispatch() }

// Register request to time out unless Manager.Cancel is called
// before the timeout duration passes, with the same request parameters.
func (m *Manager) Register(validatorID ids.ShortID, chainID ids.ID, requestID uint32, timeout func()) (time.Time, bool) {
	if ok := m.benchlist.RegisterQuery(chainID, validatorID, requestID); !ok {
		timeout() // TODO use executor to execute asynchronously
		return time.Time{}, false
	}
	return m.tm.Put(createRequestID(validatorID, chainID, requestID), func() {
		m.benchlist.QueryFailed(chainID, validatorID, requestID)
		timeout()
	}), true
}

// Cancel request timeout with the specified parameters.
func (m *Manager) Cancel(validatorID ids.ShortID, chainID ids.ID, requestID uint32) {
	m.benchlist.RegisterResponse(chainID, validatorID, requestID)
	m.tm.Remove(createRequestID(validatorID, chainID, requestID))
}

func createRequestID(validatorID ids.ShortID, chainID ids.ID, requestID uint32) ids.ID {
	p := wrappers.Packer{Bytes: make([]byte, wrappers.IntLen)}
	p.PackInt(requestID)

	return ids.NewID(hashing.ByteArraysToHash256Array(validatorID.Bytes(), chainID.Bytes(), p.Bytes))
}
<commit_msg>Execute timeout function using executor<commit_after>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package timeout

import (
	"time"

	"github.com/ava-labs/avalanchego/ids"
	"github.com/ava-labs/avalanchego/snow/networking/benchlist"
	"github.com/ava-labs/avalanchego/utils/hashing"
	"github.com/ava-labs/avalanchego/utils/timer"
	"github.com/ava-labs/avalanchego/utils/wrappers"
)

// Manager registers and fires timeouts for the snow API.
type Manager struct {
	tm        timer.AdaptiveTimeoutManager
	benchlist benchlist.Manager
	executor  timer.Executor
}

// Initialize this timeout manager.
func (m *Manager) Initialize(timeoutConfig *timer.AdaptiveTimeoutConfig, benchlist benchlist.Manager) error {
	m.benchlist = benchlist
	m.executor.Initialize()
	return m.tm.Initialize(timeoutConfig)
}

// Dispatch ...
func (m *Manager) Dispatch() {
	go m.executor.Dispatch()
	m.tm.Dispatch()
}

// Register request to time out unless Manager.Cancel is called
// before the timeout duration passes, with the same request parameters.
func (m *Manager) Register(validatorID ids.ShortID, chainID ids.ID, requestID uint32, timeout func()) (time.Time, bool) {
	if ok := m.benchlist.RegisterQuery(chainID, validatorID, requestID); !ok {
		m.executor.Add(timeout)
		return time.Time{}, false
	}
	return m.tm.Put(createRequestID(validatorID, chainID, requestID), func() {
		m.benchlist.QueryFailed(chainID, validatorID, requestID)
		timeout()
	}), true
}

// Cancel request timeout with the specified parameters.
func (m *Manager) Cancel(validatorID ids.ShortID, chainID ids.ID, requestID uint32) {
	m.benchlist.RegisterResponse(chainID, validatorID, requestID)
	m.tm.Remove(createRequestID(validatorID, chainID, requestID))
}

func createRequestID(validatorID ids.ShortID, chainID ids.ID, requestID uint32) ids.ID {
	p := wrappers.Packer{Bytes: make([]byte, wrappers.IntLen)}
	p.PackInt(requestID)

	return ids.NewID(hashing.ByteArraysToHash256Array(validatorID.Bytes(), chainID.Bytes(), p.Bytes))
}
<|endoftext|>


<commit_before>// +build f10x_ld f10x_ld_vl f10x_md f10x_md_vl f10x_hd f10x_hd_vl f10x_xl

package rtc

import (
	"bits"
	"math"
	"rtos"
	"sync/fence"
	"syscall"
	"time"

	"arch/cortexm/bitband"

	"stm32/hal/exti"
	"stm32/hal/irq"

	"stm32/hal/raw/bkp"
	"stm32/hal/raw/pwr"
	"stm32/hal/raw/rcc"
	"stm32/hal/raw/rtc"
)

// When 32768 Hz oscilator is used and preLog2 == 5 then:
// - rtos.Nanosec resolution is 1/32768 s,
// - rtos.SleepUntil resoultion is 1<<5/32768 s = 1/1024 s ≈ 1 ms,
// - the longest down time (RTC on battery) can be 1<<32/1024 s ≈ 48 days.
const (
	preLog2   = 5
	prescaler = 1 << preLog2

	maxSleepCnt = 1 << 22 // Do not sleep to long to not affect max down time.

	flagOK  = 0
	flagSet = 1
)

type globals struct {
	wakens  int64
	freqHz  uint
	cntExt  int32  // 16 bit RTC VCNT excension.
	lastISR uint32 // Last ISR time using uint32(loadVCNT() >> preLog2).
	status  bitband.Bits16
	alarm   bool
}

var g globals

func init() {
	status := rtcBackup{bkp.BKP}.Status()
	g.status = bitband.Alias16(status)
}

func setup(freqHz uint) {
	g.freqHz = freqHz

	RTC := rtc.RTC
	RCC := rcc.RCC
	PWR := pwr.PWR
	bkp := rtcBackup{bkp.BKP}

	const (
		mask = rcc.LSEON | rcc.RTCSEL | rcc.RTCEN
		cfg  = rcc.LSEON | rcc.RTCSEL_LSE | rcc.RTCEN
	)

	// Enable write access to backup domain.
	RCC.APB1ENR.SetBits(rcc.PWREN | rcc.BKPEN)
	_ = RCC.APB1ENR.Load()
	PWR.DBP().Set()
	RCC.APB1ENR.ClearBits(rcc.PWREN)

	if RCC.BDCR.Bits(mask) != cfg || g.status.Bit(flagOK).Load() == 0 {
		// RTC not initialized or in dirty state.

		// Reset backup domain and configure RTC clock source.
		RCC.BDRST().Set()
		RCC.BDRST().Clear()
		RCC.LSEON().Set()
		for RCC.LSERDY().Load() == 0 {
		}
		RCC.BDCR.StoreBits(mask, cfg)

		// Configure RTC prescaler.
		waitForSync(RTC)
		waitForWrite(RTC)
		setCNF(RTC) // Begin PRL configuration
		RTC.PRLL.Store(prescaler - 1)
		clearCNF(RTC) // Copy from APB to BKP domain.

		g.status.Bit(flagOK).Set()

		// Wait for complete before setup RTCALR interrupt.
		waitForWrite(RTC)
	} else {
		g.cntExt = int32(int16(bkp.CntExt().Load()))
		g.lastISR = bkp.LastISR().Load()
		if g.status.Bit(flagSet).Load() != 0 {
			sec := bkp.StartSec().Load()
			ns := int32(bkp.StartNanosec().Load())
			start := time.Unix(int64(sec), int64(ns))
			time.SetStart(start)
		}
	}
	// Wait for sync. Need in both cases: after reset (synchronise APB domain)
	// or after configuration (avoid reading bad DIVL).
	waitForSync(RTC)

	exti.RTCALR.EnableRisiTrig()
	exti.RTCALR.EnableIRQ()
	// BUG: EnableEvent must be used to wakeup from deep-sleep (STM32 stop).
	spnum := rtos.IRQPrioStep * rtos.IRQPrioNum
	rtos.IRQ(irq.RTCAlarm).SetPrio(rtos.IRQPrioLowest + spnum*3/4)
	rtos.IRQ(irq.RTCAlarm).Enable()

	syscall.SetSysTimer(nanosec, setWakeup)

	// Force RTCISR to initialise or early handle possible overflow.
	exti.RTCALR.Trigger()
}

// loadVCNT returns value of virtual counter that counts number of ticks of
// RTC input clock. Value of this virtual counter is calculated according to
// the formula:
//
//  VCNT = ((CNTH<<16 + CNTL)<<preLog2 + frac) & (prescaler<<32 - 1)
//
// where frac is calculated as follow:
//
//  frac = prescaler - (DIVL+1)&(prescaler-1)
//
// Only DIVL is used, so prescaler can not be greater than 0x10000.
//
// Thanks to this transformation, RTC interrupts are generated at right time.
// See example for Second, Overflow and Alarm(0-1) interrupts in table below:
//
//  CNT      DIV| VCNT>>5 VCNT&0x1f
//  ------------+--------------------
//  ffffffff 04 | ffffffff 1b
//  ffffffff 03 | ffffffff 1c
//  ffffffff 02 | ffffffff 1d
//  ffffffff 01 | ffffffff 1e
//  ffffffff 00 | ffffffff 1f
//  ffffffff 1f | 00000000 00 <- Second, Overflow, Alarm(0xffffffff)
//  00000000 1e | 00000000 01
//  00000000 1d | 00000000 02
//  00000000 1c | 00000000 03
//  00000000 1b | 00000000 04
//  00000000 1a | 00000000 05
//
func loadVCNT() int64 {
	RTC := rtc.RTC
	var (
		ch rtc.CNTH_Bits
		cl rtc.CNTL_Bits
		dl rtc.DIVL_Bits
	)
	ch = RTC.CNTH.Load()
	for {
		cl = RTC.CNTL.Load()
		for {
			dl = RTC.DIVL.Load()
			cl1 := RTC.CNTL.Load()
			if cl1 == cl {
				break
			}
			cl = cl1
		}
		ch1 := RTC.CNTH.Load()
		if ch1 == ch {
			break
		}
		ch = ch1
	}
	cnt := uint32(ch)<<16 | uint32(cl)
	frac := prescaler - (uint32(dl)+1)&(prescaler-1)
	return (int64(cnt)<<preLog2 + int64(frac)) & (prescaler<<32 - 1)
}

func isr() {
	exti.RTCALR.ClearPending()
	g.wakens = 0 // Invalidate g.wakens.
	vcnt32 := uint32(loadVCNT() >> preLog2)
	if vcnt32 != g.lastISR {
		bkp := rtcBackup{bkp.BKP}
		if vcnt32 < g.lastISR {
			cntext := g.cntExt + 1
			g.status.Bit(flagOK).Clear()
			bkp.CntExt().Store(uint16(cntext))
			bkp.LastISR().Store(vcnt32)
			g.status.Bit(flagOK).Set()
			g.cntExt = cntext // Ordinary store (load only when IRQ disabled).
		} else {
			bkp.LastISR().Store(vcnt32)
		}
		g.lastISR = vcnt32 // Ordinary store (load only when IRQ disabled).
	}
	if g.alarm {
		g.alarm = false
		syscall.Alarm.Send()
	} else {
		syscall.SchedNext()
	}
}

func loadTicks() int64 {
	irq.RTCAlarm.Disable()
	fence.Memory()
	lastisr := g.lastISR
	cntext := g.cntExt
	vcnt := loadVCNT()
	fence.Memory()
	irq.RTCAlarm.Enable()

	if uint32(vcnt>>preLog2) < lastisr {
		cntext++
	}
	return int64(cntext)<<(32+preLog2) | vcnt
}

// nanosec: see syscall.SetSysClock.
func nanosec() int64 {
	return ticktons(loadTicks())
}

// setWakeup: see syscall.SetSysTimer.
func setWakeup(ns int64, alarm bool) {
	if g.wakens == ns && g.alarm == alarm {
		return
	}
	// Use EXTI instead of NVIC to actually disable IRQ source and not colide
	// with loadTicks.
	exti.RTCALR.DisableIRQ()
	fence.Memory()
	g.wakens = ns
	g.alarm = alarm

	now := loadTicks() >> preLog2
	wkup := (nstotick(ns) + prescaler - 1) >> preLog2
	nowcnt := uint32(now)
	cntfromisr := nowcnt - g.lastISR
	alrcnt := nowcnt
	if cntfromisr < maxSleepCnt {
		maxwkup := now + int64(maxSleepCnt-cntfromisr)
		if wkup > maxwkup {
			wkup = maxwkup
		}
		alrcnt = uint32(wkup)
	}
	alrcnt-- // See loadVCNT description.

	RTC := rtc.RTC
	waitForWrite(RTC)
	setCNF(RTC)
	RTC.ALRH.Store(rtc.ALRH_Bits(alrcnt >> 16))
	RTC.ALRL.Store(rtc.ALRL_Bits(alrcnt))
	clearCNF(RTC)

	fence.Memory() // Ensure that g.* fields are stored.
	exti.RTCALR.EnableIRQ()

	now = loadTicks() >> preLog2
	if now >= wkup {
		// There is a chance that the alarm interrupt was not triggered.
		exti.RTCALR.Trigger()
	}

	/*print64("*sw* now:", now)
	print64(" wkup:", wkup)
	print32(" cnt1:", uint32(now>>rtcPreLog2))
	println32(" alr:", alr)*/
}

func setStartTime(t time.Time) {
	bkp := rtcBackup{bkp.BKP}
	if g.status.Bit(flagOK).Load() == 0 {
		return
	}
	sec := t.Unix()
	ns := t.Nanosecond()
	time.SetStart(t)
	g.status.Bit(flagOK).Clear()
	bkp.StartSec().Store(uint64(sec))
	bkp.StartNanosec().Store(uint32(ns))
	bkp.Status().Store(1<<flagSet | 1<<flagOK)
}

func status() (ok, set bool) {
	s := rtcBackup{bkp.BKP}.Status().Load()
	ok = s&(1<<flagOK) != 0
	set = s&(1<<flagSet) != 0
	return
}

func ticktons(tick int64) int64 {
	return int64(math.Muldiv(uint64(tick), 1e9, uint64(g.freqHz)))
}

func nstotick(ns int64) int64 {
	return int64(math.Muldiv(uint64(ns), uint64(g.freqHz), 1e9))
}
<commit_msg>stm32/hal/system/timer/rtc: Remove unned bits import.<commit_after>// +build f10x_ld f10x_ld_vl f10x_md f10x_md_vl f10x_hd f10x_hd_vl f10x_xl

package rtc

import (
	"math"
	"rtos"
	"sync/fence"
	"syscall"
	"time"

	"arch/cortexm/bitband"

	"stm32/hal/exti"
	"stm32/hal/irq"

	"stm32/hal/raw/bkp"
	"stm32/hal/raw/pwr"
	"stm32/hal/raw/rcc"
	"stm32/hal/raw/rtc"
)

// When 32768 Hz oscilator is used and preLog2 == 5 then:
// - rtos.Nanosec resolution is 1/32768 s,
// - rtos.SleepUntil resoultion is 1<<5/32768 s = 1/1024 s ≈ 1 ms,
// - the longest down time (RTC on battery) can be 1<<32/1024 s ≈ 48 days.
const (
	preLog2   = 5
	prescaler = 1 << preLog2

	maxSleepCnt = 1 << 22 // Do not sleep to long to not affect max down time.

	flagOK  = 0
	flagSet = 1
)

type globals struct {
	wakens  int64
	freqHz  uint
	cntExt  int32  // 16 bit RTC VCNT excension.
	lastISR uint32 // Last ISR time using uint32(loadVCNT() >> preLog2).
	status  bitband.Bits16
	alarm   bool
}

var g globals

func init() {
	status := rtcBackup{bkp.BKP}.Status()
	g.status = bitband.Alias16(status)
}

func setup(freqHz uint) {
	g.freqHz = freqHz

	RTC := rtc.RTC
	RCC := rcc.RCC
	PWR := pwr.PWR
	bkp := rtcBackup{bkp.BKP}

	const (
		mask = rcc.LSEON | rcc.RTCSEL | rcc.RTCEN
		cfg  = rcc.LSEON | rcc.RTCSEL_LSE | rcc.RTCEN
	)

	// Enable write access to backup domain.
	RCC.APB1ENR.SetBits(rcc.PWREN | rcc.BKPEN)
	_ = RCC.APB1ENR.Load()
	PWR.DBP().Set()
	RCC.APB1ENR.ClearBits(rcc.PWREN)

	if RCC.BDCR.Bits(mask) != cfg || g.status.Bit(flagOK).Load() == 0 {
		// RTC not initialized or in dirty state.

		// Reset backup domain and configure RTC clock source.
		RCC.BDRST().Set()
		RCC.BDRST().Clear()
		RCC.LSEON().Set()
		for RCC.LSERDY().Load() == 0 {
		}
		RCC.BDCR.StoreBits(mask, cfg)

		// Configure RTC prescaler.
		waitForSync(RTC)
		waitForWrite(RTC)
		setCNF(RTC) // Begin PRL configuration
		RTC.PRLL.Store(prescaler - 1)
		clearCNF(RTC) // Copy from APB to BKP domain.

		g.status.Bit(flagOK).Set()

		// Wait for complete before setup RTCALR interrupt.
		waitForWrite(RTC)
	} else {
		g.cntExt = int32(int16(bkp.CntExt().Load()))
		g.lastISR = bkp.LastISR().Load()
		if g.status.Bit(flagSet).Load() != 0 {
			sec := bkp.StartSec().Load()
			ns := int32(bkp.StartNanosec().Load())
			start := time.Unix(int64(sec), int64(ns))
			time.SetStart(start)
		}
	}
	// Wait for sync. Need in both cases: after reset (synchronise APB domain)
	// or after configuration (avoid reading bad DIVL).
	waitForSync(RTC)

	exti.RTCALR.EnableRisiTrig()
	exti.RTCALR.EnableIRQ()
	// BUG: EnableEvent must be used to wakeup from deep-sleep (STM32 stop).
	spnum := rtos.IRQPrioStep * rtos.IRQPrioNum
	rtos.IRQ(irq.RTCAlarm).SetPrio(rtos.IRQPrioLowest + spnum*3/4)
	rtos.IRQ(irq.RTCAlarm).Enable()

	syscall.SetSysTimer(nanosec, setWakeup)

	// Force RTCISR to initialise or early handle possible overflow.
	exti.RTCALR.Trigger()
}

// loadVCNT returns value of virtual counter that counts number of ticks of
// RTC input clock. Value of this virtual counter is calculated according to
// the formula:
//
//  VCNT = ((CNTH<<16 + CNTL)<<preLog2 + frac) & (prescaler<<32 - 1)
//
// where frac is calculated as follow:
//
//  frac = prescaler - (DIVL+1)&(prescaler-1)
//
// Only DIVL is used, so prescaler can not be greater than 0x10000.
//
// Thanks to this transformation, RTC interrupts are generated at right time.
// See example for Second, Overflow and Alarm(0-1) interrupts in table below:
//
//  CNT      DIV| VCNT>>5 VCNT&0x1f
//  ------------+--------------------
//  ffffffff 04 | ffffffff 1b
//  ffffffff 03 | ffffffff 1c
//  ffffffff 02 | ffffffff 1d
//  ffffffff 01 | ffffffff 1e
//  ffffffff 00 | ffffffff 1f
//  ffffffff 1f | 00000000 00 <- Second, Overflow, Alarm(0xffffffff)
//  00000000 1e | 00000000 01
//  00000000 1d | 00000000 02
//  00000000 1c | 00000000 03
//  00000000 1b | 00000000 04
//  00000000 1a | 00000000 05
//
func loadVCNT() int64 {
	RTC := rtc.RTC
	var (
		ch rtc.CNTH_Bits
		cl rtc.CNTL_Bits
		dl rtc.DIVL_Bits
	)
	ch = RTC.CNTH.Load()
	for {
		cl = RTC.CNTL.Load()
		for {
			dl = RTC.DIVL.Load()
			cl1 := RTC.CNTL.Load()
			if cl1 == cl {
				break
			}
			cl = cl1
		}
		ch1 := RTC.CNTH.Load()
		if ch1 == ch {
			break
		}
		ch = ch1
	}
	cnt := uint32(ch)<<16 | uint32(cl)
	frac := prescaler - (uint32(dl)+1)&(prescaler-1)
	return (int64(cnt)<<preLog2 + int64(frac)) & (prescaler<<32 - 1)
}

func isr() {
	exti.RTCALR.ClearPending()
	g.wakens = 0 // Invalidate g.wakens.
	vcnt32 := uint32(loadVCNT() >> preLog2)
	if vcnt32 != g.lastISR {
		bkp := rtcBackup{bkp.BKP}
		if vcnt32 < g.lastISR {
			cntext := g.cntExt + 1
			g.status.Bit(flagOK).Clear()
			bkp.CntExt().Store(uint16(cntext))
			bkp.LastISR().Store(vcnt32)
			g.status.Bit(flagOK).Set()
			g.cntExt = cntext // Ordinary store (load only when IRQ disabled).
		} else {
			bkp.LastISR().Store(vcnt32)
		}
		g.lastISR = vcnt32 // Ordinary store (load only when IRQ disabled).
	}
	if g.alarm {
		g.alarm = false
		syscall.Alarm.Send()
	} else {
		syscall.SchedNext()
	}
}

func loadTicks() int64 {
	irq.RTCAlarm.Disable()
	fence.Memory()
	lastisr := g.lastISR
	cntext := g.cntExt
	vcnt := loadVCNT()
	fence.Memory()
	irq.RTCAlarm.Enable()

	if uint32(vcnt>>preLog2) < lastisr {
		cntext++
	}
	return int64(cntext)<<(32+preLog2) | vcnt
}

// nanosec: see syscall.SetSysClock.
func nanosec() int64 {
	return ticktons(loadTicks())
}

// setWakeup: see syscall.SetSysTimer.
func setWakeup(ns int64, alarm bool) {
	if g.wakens == ns && g.alarm == alarm {
		return
	}
	// Use EXTI instead of NVIC to actually disable IRQ source and not colide
	// with loadTicks.
	exti.RTCALR.DisableIRQ()
	fence.Memory()
	g.wakens = ns
	g.alarm = alarm

	now := loadTicks() >> preLog2
	wkup := (nstotick(ns) + prescaler - 1) >> preLog2
	nowcnt := uint32(now)
	cntfromisr := nowcnt - g.lastISR
	alrcnt := nowcnt
	if cntfromisr < maxSleepCnt {
		maxwkup := now + int64(maxSleepCnt-cntfromisr)
		if wkup > maxwkup {
			wkup = maxwkup
		}
		alrcnt = uint32(wkup)
	}
	alrcnt-- // See loadVCNT description.

	RTC := rtc.RTC
	waitForWrite(RTC)
	setCNF(RTC)
	RTC.ALRH.Store(rtc.ALRH_Bits(alrcnt >> 16))
	RTC.ALRL.Store(rtc.ALRL_Bits(alrcnt))
	clearCNF(RTC)

	fence.Memory() // Ensure that g.* fields are stored.
	exti.RTCALR.EnableIRQ()

	now = loadTicks() >> preLog2
	if now >= wkup {
		// There is a chance that the alarm interrupt was not triggered.
		exti.RTCALR.Trigger()
	}

	/*print64("*sw* now:", now)
	print64(" wkup:", wkup)
	print32(" cnt1:", uint32(now>>rtcPreLog2))
	println32(" alr:", alr)*/
}

func setStartTime(t time.Time) {
	bkp := rtcBackup{bkp.BKP}
	if g.status.Bit(flagOK).Load() == 0 {
		return
	}
	sec := t.Unix()
	ns := t.Nanosecond()
	time.SetStart(t)
	g.status.Bit(flagOK).Clear()
	bkp.StartSec().Store(uint64(sec))
	bkp.StartNanosec().Store(uint32(ns))
	bkp.Status().Store(1<<flagSet | 1<<flagOK)
}

func status() (ok, set bool) {
	s := rtcBackup{bkp.BKP}.Status().Load()
	ok = s&(1<<flagOK) != 0
	set = s&(1<<flagSet) != 0
	return
}

func ticktons(tick int64) int64 {
	return int64(math.Muldiv(uint64(tick), 1e9, uint64(g.freqHz)))
}

func nstotick(ns int64) int64 {
	return int64(math.Muldiv(uint64(ns), uint64(g.freqHz), 1e9))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	//        "io"
	"io/ioutil"
	"path"
	//        "strings"
	"encoding/csv"
	"os"
	"strconv"
)

func checkErr(e error) {
	if e != nil {
		fmt.Println("Poop! Error encountered:", e)
		os.Exit(1)
	}
}

// Removes non-directory elements of any []os.FileInfo
func onlyDirectories(potential_files []os.FileInfo) (out_ls []os.FileInfo) {
	for _, fd := range potential_files {
		if fd.IsDir() {
			out_ls = append(out_ls, fd)
		}
	}
	return
}

// Extend "records" matrix to have rows until time "desired_time"
// Return: Extended version of record
func extendRecordsToTime(records [][]string, desired_time int, record_cols int) [][]string {
	lenr := len(records)
	// records[1] stores cycle [1], as records[0] is column names
	for j := lenr; j < desired_time+1; j++ {
		records = append(records, make([]string, record_cols))
		records[j][0] = strconv.Itoa(j)
	}
	return records
}

// Enters all report subdirectories, from benchmark to fengine to trial;
// composes individual CSVs (only two columns) into larger CSVs
func composeAllNamed(desired_report_fname string) {
	master_path := "./reports"
	bmarks, err := ioutil.ReadDir(master_path)
	checkErr(err)
	for _, bmark := range bmarks {
		// all_fe_file, err := os.Create(path.Join(master_path, bmark.Name(), desired_report_fname))
		// checkErr(err)
		// defer all_fe_file.Close()
		// all_fe_writer := csv.NewWriter(all_fe_file)
		// meta_records := [][]string{{"time"}}
		potential_fengines, err := ioutil.ReadDir(path.Join(master_path, bmark.Name()))
		checkErr(err)
		// narrow potential_fengines to fengines so the indices of `range fengines` are useful
		fengines := onlyDirectories(potential_fengines)

		for _, fengine := range fengines {
			// Create fds
			this_fe_file, err := os.Create(path.Join(master_path, bmark.Name(), fengine.Name(), desired_report_fname))
			checkErr(err)
			defer this_fe_file.Close()
			this_fe_writer := csv.NewWriter(this_fe_file)

			// Create matrix, to eventually become a CSV
			records := [][]string{{"time"}}

			// Enter sub-directories
			potential_trials, err := ioutil.ReadDir(path.Join(master_path, bmark.Name(), fengine.Name()))
			checkErr(err)
			trials := onlyDirectories(potential_trials)

			num_record_columns := len(trials) + 1
			for j, trial := range trials {
				// Create fds
				this_file, err := os.Open(path.Join(master_path, bmark.Name(), fengine.Name(), trial.Name(), desired_report_fname))
				checkErr(err)
				defer this_file.Close()
				this_reader := csv.NewReader(this_file)

				// Read whole CSV to an array
				experiment_records, err := this_reader.ReadAll()
				checkErr(err)
				// Add the name of this new column to records[0]
				records[0] = append(records[0], fengine.Name()+trial.Name())

				final_time, err := strconv.Atoi(experiment_records[len(experiment_records)-1][0])
				checkErr(err)
				//If this test went longer than all of the others, so far
				if len(records) < final_time+1 {
					records = extendRecordsToTime(records, final_time, num_record_columns)
				}
				for _, row := range experiment_records {
					// row[0] is time, on the x-axis; row[1] is value, on the y-axis
					time_now, err := strconv.Atoi(row[0])
					checkErr(err)
					records[time_now][j+1] = row[1]
				}
			}
			this_fe_writer.WriteAll(records)
			// Potentially put this fengine into a broader comparison CSV
		}
		// TODO: create comparison between fengines, having already composed trials
		// Do this by identifying the max (or potentially median) performing trial
		// For each fengine, and putting them all into a CSV which can be graphed
	}
}

func main() {
	composeAllNamed("coverage-graph.csv")
	composeAllNamed("corpus-size-graph.csv")
	composeAllNamed("corpus-elems-graph.csv")
	// createIFramesFor("setOfFrames.html")
	//
}
<commit_msg>Approach less nesting for reportgen<commit_after>package main

import (
	"fmt"
	//	"io"
	"io/ioutil"
	"path"
	//        "strings"
	"encoding/csv"
	"os"
	"strconv"
)

func checkErr(e error) {
	if e != nil {
		fmt.Println("Poop! Error encountered:", e)
		os.Exit(1)
	}
}

// Removes non-directory elements of any []os.FileInfo
func onlyDirectories(potential_files []os.FileInfo) (out_ls []os.FileInfo) {
	for _, fd := range potential_files {
		if fd.IsDir() {
			out_ls = append(out_ls, fd)
		}
	}
	return
}

// Extend "records" matrix to have rows until time "desired_time"
// Return: Extended version of record
func extendRecordsToTime(records [][]string, desired_time int, record_cols int) [][]string {
	lenr := len(records)
	// records[1] stores cycle [1], as records[0] is column names
	for j := lenr; j < desired_time+1; j++ {
		records = append(records, make([]string, record_cols))
		records[j][0] = strconv.Itoa(j)
	}
	return records
}

//func csvWrapper( )
//func csvWriterWrapper( ) *Writer

// Handles the CSV Reader for a single trial, and updates records[][] accordingly. Returns the updated records
func handleTrialCSV(this_reader *csv.Reader, records [][]string, fengine os.FileInfo, trial os.FileInfo, num_record_columns int, j int) [][]string {
	// Read whole CSV to an array
	experiment_records, err := this_reader.ReadAll()
	checkErr(err)
	// Add the name of this new column to records[0]
	records[0] = append(records[0], fengine.Name()+trial.Name())

	final_time, err := strconv.Atoi(experiment_records[len(experiment_records)-1][0])
	checkErr(err)
	//If this test went longer than all of the others, so far
	if len(records) < final_time+1 {
		records = extendRecordsToTime(records, final_time, num_record_columns)
	}
	for _, row := range experiment_records {
		// row[0] is time, on the x-axis; row[1] is value, on the y-axis
		time_now, err := strconv.Atoi(row[0])
		checkErr(err)
		records[time_now][j+1] = row[1]
	}
	return records
}

// Enters all report subdirectories, from benchmark to fengine to trial;
// composes individual CSVs (only two columns) into larger CSVs
func composeAllNamed(desired_report_fname string) {
	master_path := "./reports"
	bmarks, err := ioutil.ReadDir(master_path)
	checkErr(err)
	for _, bmark := range bmarks {
		// all_fe_file, err := os.Create(path.Join(master_path, bmark.Name(), desired_report_fname))
		// checkErr(err)
		// defer all_fe_file.Close()
		// all_fe_writer := csv.NewWriter(all_fe_file)
		// meta_records := [][]string{{"time"}}
		potential_fengines, err := ioutil.ReadDir(path.Join(master_path, bmark.Name()))
		checkErr(err)
		// narrow potential_fengines to fengines so the indices of `range fengines` are useful
		fengines := onlyDirectories(potential_fengines)

		for _, fengine := range fengines {
			// Create fds
			this_fe_file, err := os.Create(path.Join(master_path, bmark.Name(), fengine.Name(), desired_report_fname))
			checkErr(err)
			defer this_fe_file.Close()
			this_fe_writer := csv.NewWriter(this_fe_file)

			// Create matrix, to eventually become a CSV
			records := [][]string{{"time"}}

			// Enter sub-directories
			potential_trials, err := ioutil.ReadDir(path.Join(master_path, bmark.Name(), fengine.Name()))
			checkErr(err)
			trials := onlyDirectories(potential_trials)

			num_record_columns := len(trials) + 1
			for j, trial := range trials {
				// Create fds
				this_file, err := os.Open(path.Join(master_path, bmark.Name(), fengine.Name(), trial.Name(), desired_report_fname))
				checkErr(err)
				defer this_file.Close()
				this_reader := csv.NewReader(this_file)

				// INNER LOOP
				records = handleTrialCSV(this_reader, records, fengine, trial, num_record_columns, j)

			}
			this_fe_writer.WriteAll(records)
			// Potentially put this fengine into a broader comparison CSV
		}
		// TODO: create comparison between fengines, having already composed trials
		// Do this by identifying the max (or potentially median) performing trial
		// For each fengine, and putting them all into a CSV which can be graphed
	}
}

func main() {
	composeAllNamed("coverage-graph.csv")
	composeAllNamed("corpus-size-graph.csv")
	composeAllNamed("corpus-elems-graph.csv")
	// createIFramesFor("setOfFrames.html")
	//
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"text/template"
)

// Map describes a mapping between database tables and Go structs.
type Map []TableMap

// TableMap describes a mapping between a Go struct and database table.
type TableMap struct {
	Struct  string      `json:"struct"`
	Table   string      `json:"table"`
	Columns []ColumnMap `json:"columns"`
}

type importSpec struct {
	path string
	name string
}

func (i importSpec) String() string {
	if i.name == "" {
		return "\"" + i.path + "\""
	}
	return fmt.Sprintf("%s \"%s\"", i.name, i.path)
}

func (t TableMap) Imports() []importSpec {
	return []importSpec{
		{"database/sql", ""},
		{"github.com/lib/pq", "_"},
	}
}

func (t TableMap) ColumnList() string {
	cols := []string{t.PKCol()}
	for _, col := range t.Columns {
		cols = append(cols, col.Column)
	}
	return strings.Join(cols, ", ")
}

func (t TableMap) UpdateList() string {
	cols := []string{}
	for i, col := range t.Columns {
		cols = append(cols, fmt.Sprintf("%s = $%d", col.Column, i+2))
	}
	return strings.Join(cols, ", ")
}

func (t TableMap) InsertList() string {
	cols := []string{"$1"}
	for i := range t.Columns {
		cols = append(cols, fmt.Sprintf("$%d", i+2))
	}
	return strings.Join(cols, ", ")
}

func (t TableMap) PKCol() string {
	return "id"
}

func (t TableMap) Fields() []string {
	f := []string{"ID"}
	for i := range t.Columns {
		f = append(f, t.Columns[i].Field)
	}
	return f
}

// ColumnMap describes a mapping between a Go struct field and a database
// column.
type ColumnMap struct {
	Field  string `json:"field"`
	Column string `json:"column"`
	Type   string `json:"type"`
}

type Code struct {
	buf  *bytes.Buffer
	tmpl *template.Template
	dest string
}

func (c Code) write(format string, param ...interface{}) {
	c.buf.WriteString(fmt.Sprintf(format, param...))
}

func (c Code) Gen(mapper Map, pkg string) {
	for i, tableMap := range mapper {
		log.Printf("%d: generating %s", i, tableMap.Struct)
		c.genMapper(tableMap, pkg)
		filename := strings.ToLower(tableMap.Struct) + "_mapper.go"
		path := c.dest + "/" + filename
		f, err := os.Create(path)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		if _, err := c.buf.WriteTo(f); err != nil {
			log.Fatal(err)
		}
		c.buf.Reset()
	}
	// Auxiliary support for mapper - Scanner interface
	path := c.dest + "/" + "scanner.go"
	f, err := os.Create(path)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	fmt.Fprintf(f, "package %s\n\n", pkg)
	fmt.Fprintf(f, "type Scanner interface {\n")
	fmt.Fprintf(f, "\tScan(...interface{}) error\n")
	fmt.Fprintf(f, "}\n")
}

func (c Code) genMapper(mapper TableMap, pkg string) {
	mapperFields := []string{"db *sql.DB"}
	data := struct {
		Package      string
		Imports      []importSpec
		MapperType   string
		MapperFields []string
		VarName      string
		StructType   string
		ColumnList   string
		Table        string
		PKCol        string
		Fields       []string
		UpdateList   string
		UpdateCount  int
		InsertList   string
	}{
		pkg,
		mapper.Imports(),
		mapper.Struct + "Mapper",
		mapperFields,
		strings.ToLower(mapper.Struct[0:1]),
		mapper.Struct,
		mapper.ColumnList(),
		mapper.Table,
		mapper.PKCol(),
		mapper.Fields(),
		mapper.UpdateList(),
		len(mapper.Columns) + 1,
		mapper.InsertList(),
	}
	if err := c.tmpl.Execute(c.buf, data); err != nil {
		log.Fatal(err)
	}
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage: %s <metadata_file> <output_dir>\n", os.Args[0])
}

func main() {
	flag.Usage = usage

	flag.Parse()

	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(1)
	}

	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	var mapper Map
	if err := json.NewDecoder(f).Decode(&mapper); err != nil {
		log.Fatal(err)
	}

	code := Code{
		buf:  bytes.NewBuffer(nil),
		tmpl: template.Must(template.New("tablestruct").Parse(mapperTemplate)),
		dest: flag.Arg(1),
	}
	code.Gen(mapper, "main")
}
<commit_msg>gofmt the generated code<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"go/format"
	"go/parser"
	"go/token"
	"log"
	"os"
	"strings"
	"text/template"
)

// Map describes a mapping between database tables and Go structs.
type Map []TableMap

// TableMap describes a mapping between a Go struct and database table.
type TableMap struct {
	Struct  string      `json:"struct"`
	Table   string      `json:"table"`
	Columns []ColumnMap `json:"columns"`
}

type importSpec struct {
	path string
	name string
}

func (i importSpec) String() string {
	if i.name == "" {
		return "\"" + i.path + "\""
	}
	return fmt.Sprintf("%s \"%s\"", i.name, i.path)
}

func (t TableMap) Imports() []importSpec {
	return []importSpec{
		{"database/sql", ""},
		{"github.com/lib/pq", "_"},
	}
}

func (t TableMap) ColumnList() string {
	cols := []string{t.PKCol()}
	for _, col := range t.Columns {
		cols = append(cols, col.Column)
	}
	return strings.Join(cols, ", ")
}

func (t TableMap) UpdateList() string {
	cols := []string{}
	for i, col := range t.Columns {
		cols = append(cols, fmt.Sprintf("%s = $%d", col.Column, i+2))
	}
	return strings.Join(cols, ", ")
}

func (t TableMap) InsertList() string {
	cols := []string{"$1"}
	for i := range t.Columns {
		cols = append(cols, fmt.Sprintf("$%d", i+2))
	}
	return strings.Join(cols, ", ")
}

func (t TableMap) PKCol() string {
	return "id"
}

func (t TableMap) Fields() []string {
	f := []string{"ID"}
	for i := range t.Columns {
		f = append(f, t.Columns[i].Field)
	}
	return f
}

// ColumnMap describes a mapping between a Go struct field and a database
// column.
type ColumnMap struct {
	Field  string `json:"field"`
	Column string `json:"column"`
	Type   string `json:"type"`
}

type Code struct {
	buf  *bytes.Buffer
	tmpl *template.Template
	dest string
}

func (c Code) write(format string, param ...interface{}) {
	c.buf.WriteString(fmt.Sprintf(format, param...))
}

func (c Code) Gen(mapper Map, pkg string) {
	for i, tableMap := range mapper {
		log.Printf("%d: generating %s", i, tableMap.Struct)
		c.genMapper(tableMap, pkg)

		filename := strings.ToLower(tableMap.Struct) + "_mapper.go"
		path := c.dest + "/" + filename
		f, err := os.Create(path)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()

		// gofmt
		fset := token.NewFileSet()
		ast, err := parser.ParseFile(fset, "", c.buf.Bytes(), parser.ParseComments)
		if err != nil {
			log.Fatal(err)
		}
		err = format.Node(f, fset, ast)
		if err != nil {
			log.Fatal(err)
		}

		c.buf.Reset()
	}

	// Auxiliary support for mapper - Scanner interface
	path := c.dest + "/" + "scanner.go"
	f, err := os.Create(path)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	fmt.Fprintf(f, "package %s\n\n", pkg)
	fmt.Fprintf(f, "type Scanner interface {\n")
	fmt.Fprintf(f, "\tScan(...interface{}) error\n")
	fmt.Fprintf(f, "}\n")
}

func (c Code) genMapper(mapper TableMap, pkg string) {
	mapperFields := []string{"db *sql.DB"}
	data := struct {
		Package      string
		Imports      []importSpec
		MapperType   string
		MapperFields []string
		VarName      string
		StructType   string
		ColumnList   string
		Table        string
		PKCol        string
		Fields       []string
		UpdateList   string
		UpdateCount  int
		InsertList   string
	}{
		pkg,
		mapper.Imports(),
		mapper.Struct + "Mapper",
		mapperFields,
		strings.ToLower(mapper.Struct[0:1]),
		mapper.Struct,
		mapper.ColumnList(),
		mapper.Table,
		mapper.PKCol(),
		mapper.Fields(),
		mapper.UpdateList(),
		len(mapper.Columns) + 1,
		mapper.InsertList(),
	}
	if err := c.tmpl.Execute(c.buf, data); err != nil {
		log.Fatal(err)
	}
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage: %s <metadata_file> <output_dir>\n", os.Args[0])
}

func main() {
	flag.Usage = usage

	flag.Parse()

	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(1)
	}

	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	var mapper Map
	if err := json.NewDecoder(f).Decode(&mapper); err != nil {
		log.Fatal(err)
	}

	code := Code{
		buf:  bytes.NewBuffer(nil),
		tmpl: template.Must(template.New("tablestruct").Parse(mapperTemplate)),
		dest: flag.Arg(1),
	}
	code.Gen(mapper, "main")
}
<|endoftext|>


<commit_before>package server

import (
	"context"
	"net/http"
	"path"

	"github.com/gin-gonic/gin"
	"gitlab-odx.oracle.com/odx/functions/api"
)

func (s *Server) handleRouteDelete(c *gin.Context) {
	ctx := c.MustGet("ctx").(context.Context)

	appName := c.MustGet(api.AppName).(string)
	routePath := path.Clean(c.MustGet(api.Path).(string))

	if err := s.Datastore.RemoveRoute(ctx, appName, routePath); err != nil {
		handleErrorResponse(c, err)
		return
	}

	s.cachedelete(appName, routePath)
	c.JSON(http.StatusOK, gin.H{"message": "Route deleted"})
}
<commit_msg>Check if route exist before attempting to delete it<commit_after>package server

import (
	"context"
	"net/http"
	"path"

	"github.com/gin-gonic/gin"
	"gitlab-odx.oracle.com/odx/functions/api"
)

func (s *Server) handleRouteDelete(c *gin.Context) {
	ctx := c.MustGet("ctx").(context.Context)

	appName := c.MustGet(api.AppName).(string)
	routePath := path.Clean(c.MustGet(api.Path).(string))

	if _, err := s.Datastore.GetRoute(ctx, appName, routePath); err != nil {
		handleErrorResponse(c, err)
		return
	}

	if err := s.Datastore.RemoveRoute(ctx, appName, routePath); err != nil {
		handleErrorResponse(c, err)
		return
	}

	s.cachedelete(appName, routePath)
	c.JSON(http.StatusOK, gin.H{"message": "Route deleted"})
}
<|endoftext|>


<commit_before>package memosort

import (
	"testing"
	"time"
)

type Track struct {
	Title  string
	Artist string
	Album  string
	Year   int
	Length time.Duration
}

var tracks = []*Track{
	{"Go", "Delilah", "From the Roots Up", 2012, length("3m38s")},
	{"Go", "Moby", "Moby", 1992, length("3m37s")},
	{"Go Ahead", "Alicia Keys", "As I Am", 2007, length("4m36s")},
	{"Ready 2 Go", "Martin Solveig", "Smash", 2011, length("4m24s")},
	{"Bohemian Rhapsody", "Queen", "A Night at the Opera", 1975, length("6m6s")},
	{"Smells Like Teen Spirit", "Nirvana", "Nevermind", 1972, length("4m37s")},
	{"Imagine", "John Lennon", "Imagine", 1971, length("3m54s")},
	{"Hotel California", "Eagles", "Hotel California", 1976, length("6m40s")},
	{"One", "Metallica", "And Justice for All", 1988, length("7m23s")},
	{"Comfortably Numb", "Pink Floyd", "The Wall", 1979, length("6m53s")},
	{"Like a Rolling Stone", "Bob Dylan", "Highway 61 Revisited", 1965, length("6m20s")},
}

func length(s string) time.Duration {
	d, err := time.ParseDuration(s)
	if err != nil {
		panic(s)
	}
	return d
}

func TestStableSimple(t *testing.T) {

}
<commit_msg>add simple print test for memosort<commit_after>package memosort

import (
	"fmt"
	"os"
	"sort"
	"testing"
	"text/tabwriter"
	"time"
)

type Track struct {
	Title  string
	Artist string
	Album  string
	Year   int
	Length time.Duration
}

var tracks = []Track{
	{"Go", "Delilah", "From the Roots Up", 2012, length("3m38s")},
	{"Go", "Moby", "Moby", 1992, length("3m37s")},
	{"Go Ahead", "Alicia Keys", "As I Am", 2007, length("4m36s")},
	{"Ready 2 Go", "Martin Solveig", "Smash", 2011, length("4m24s")},

	// {"Comfortably Numb", "Pink Floyd", "The Wall", 1979, length("6m53s")},
	// {"Like a Rolling Stone", "Bob Dylan", "Highway 61 Revisited", 1965, length("6m20s")},
	// {"Bohemian Rhapsody", "Queen", "A Night at the Opera", 1975, length("6m6s")},
	// {"Smells Like Teen Spirit", "Nirvana", "Nevermind", 1972, length("4m37s")},
	// {"Imagine", "John Lennon", "Imagine", 1971, length("3m54s")},
	// {"Hotel California", "Eagles", "Hotel California", 1976, length("6m40s")},
	// {"One", "Metallica", "And Justice for All", 1988, length("7m23s")},
}

func length(s string) time.Duration {
	d, err := time.ParseDuration(s)
	if err != nil {
		panic(s)
	}
	return d
}

func printTracks(tracks []Track) {
	const format = "%v\t%v\t%v\t%v\t%v\t\n"
	tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
	fmt.Fprintf(tw, format, "Title", "Artist", "Album", "Year", "Length")
	fmt.Fprintf(tw, format, "-----", "------", "-----", "----", "------")
	for _, t := range tracks {
		fmt.Fprintf(tw, format, t.Title, t.Artist, t.Album, t.Year, t.Length)
	}
	fmt.Println()
	tw.Flush()
}

func TestStableSimple(t *testing.T) {
	tracksMemo := make([]Track, len(tracks))
	copy(tracksMemo, tracks)

	printTracks(tracksMemo)

	m := New()
	m.By(func(i, j int) bool { return tracksMemo[i].Title < tracksMemo[j].Title })
	m.By(func(i, j int) bool { return tracksMemo[i].Year < tracksMemo[j].Year })
	m.By(func(i, j int) bool { return tracksMemo[i].Length < tracksMemo[j].Length })
	sort.Slice(tracksMemo, m.Less)
	printTracks(tracksMemo)
}
<|endoftext|>


<commit_before>package cloudflare

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/pkg/errors"
)

type TeamsRuleSettings struct {
	// Enable block page on rules with action block
	BlockPageEnabled bool `json:"block_page_enabled"`

	// show this string at block page caused by this rule
	BlockReason string `json:"block_reason"`

	// list of ipv4 or ipv6 ips to override with, when action is set to dns override
	OverrideIPs []string `json:"override_ips"`

	// host name to override with when action is set to dns override. Can not be used with OverrideIPs
	OverrideHost string `json:"override_host"`

	// settings for l4(network) level overrides
	L4Override *TeamsL4OverrideSettings `json:"l4override"`

	// settings for adding headers to http requests
	AddHeaders http.Header `json:"add_headers"`

	// settings for browser isolation actions
	BISOAdminControls *TeamsBISOAdminControlSettings `json:"biso_admin_controls"`

	// settings for session check in allow action
	CheckSession *TeamsCheckSessionSettings `json:"check_session"`
}

// TeamsL4OverrideSettings used in l4 filter type rule with action set to override.
type TeamsL4OverrideSettings struct {
	IP   string `json:"ip,omitempty"`
	Port int    `json:"port,omitempty"`
}

type TeamsBISOAdminControlSettings struct {
	DisablePrinting  bool `json:"dp"`
	DisableCopyPaste bool `json:"dcp"`
	DisableDownload  bool `json:"dd"`
	DisableUpload    bool `json:"du"`
	DisableKeyboard  bool `json:"dk"`
}
type TeamsCheckSessionSettings struct {
	Enforce  bool     `json:"enforce"`
	Duration Duration `json:"duration"`
}

type TeamsFilterType string

type TeamsGatewayAction string

const (
	HttpFilter TeamsFilterType = "http"
	DnsFilter  TeamsFilterType = "dns"
	L4Filter   TeamsFilterType = "l4"
)

const (
	Allow        TeamsGatewayAction = "allow"
	Block        TeamsGatewayAction = "block"
	SafeSearch   TeamsGatewayAction = "safesearch"
	YTRestricted TeamsGatewayAction = "ytrestricted"
	On           TeamsGatewayAction = "on"
	Off          TeamsGatewayAction = "off"
	Scan         TeamsGatewayAction = "scan"
	NoScan       TeamsGatewayAction = "noscan"
	Isolate      TeamsGatewayAction = "isolate"
	NoIsolate    TeamsGatewayAction = "noisolate"
	Override     TeamsGatewayAction = "override"
	L4Override   TeamsGatewayAction = "l4_override"
)

func TeamsRulesActionValues() []string {
	return []string{
		string(Allow),
		string(Block),
		string(SafeSearch),
		string(YTRestricted),
		string(On),
		string(Off),
		string(Scan),
		string(NoScan),
		string(Isolate),
		string(NoIsolate),
		string(Override),
		string(L4Override),
	}
}

// TeamsRule represents an Teams wirefilter rule.
type TeamsRule struct {
	ID            string             `json:"id,omitempty"`
	CreatedAt     *time.Time         `json:"created_at,omitempty"`
	UpdatedAt     *time.Time         `json:"updated_at,omitempty"`
	DeletedAt     *time.Time         `json:"deleted_at,omitempty"`
	Name          string             `json:"name"`
	Description   string             `json:"description"`
	Precedence    uint64             `json:"precedence"`
	Enabled       bool               `json:"enabled"`
	Action        TeamsGatewayAction `json:"action"`
	Filters       []TeamsFilterType  `json:"filters"`
	Traffic       string             `json:"traffic"`
	Identity      string             `json:"identity"`
	DevicePosture string             `json:"device_posture"`
	Version       uint64             `json:"version"`
	RuleSettings  TeamsRuleSettings  `json:"rule_settings,omitempty"`
}

// TeamsRuleResponse is the API response, containing a single rule.
type TeamsRuleResponse struct {
	Response
	Result TeamsRule `json:"result"`
}

// TeamsRuleResponse is the API response, containing an array of rules.
type TeamsRulesResponse struct {
	Response
	Result []TeamsRule `json:"result"`
}

// TeamsRulePatchRequest is used to patch an existing rule.
type TeamsRulePatchRequest struct {
	ID           string             `json:"id"`
	Name         string             `json:"name"`
	Description  string             `json:"description"`
	Precedence   uint64             `json:"precedence"`
	Enabled      bool               `json:"enabled"`
	Action       TeamsGatewayAction `json:"action"`
	RuleSettings TeamsRuleSettings  `json:"rule_settings,omitempty"`
}

// TeamsRules returns all rules within an account.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsRules(ctx context.Context, accountID string) ([]TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules", accountID)

	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return []TeamsRule{}, err
	}

	var teamsRulesResponse TeamsRulesResponse
	err = json.Unmarshal(res, &teamsRulesResponse)
	if err != nil {
		return []TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRulesResponse.Result, nil
}

// TeamsRule returns the rule with rule ID in the URL.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsRule(ctx context.Context, accountID string, ruleId string) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsCreateRule creates a rule with wirefilter expression.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsCreateRule(ctx context.Context, accountID string, rule TeamsRule) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules", accountID)

	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, rule)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsUpdateRule updates a rule with wirefilter expression.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsUpdateRule(ctx context.Context, accountID string, ruleId string, rule TeamsRule) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, rule)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsPatchRule patches a rule associated values.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsPatchRule(ctx context.Context, accountID string, ruleId string, rule TeamsRulePatchRequest) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, rule)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsDeleteRule deletes a rule.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsDeleteRule(ctx context.Context, accountID string, ruleId string) error {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Update teams_rules.go<commit_after>package cloudflare

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/pkg/errors"
)

type TeamsRuleSettings struct {
	// Enable block page on rules with action block
	BlockPageEnabled bool `json:"block_page_enabled"`

	// show this string at block page caused by this rule
	BlockReason string `json:"block_reason"`

	// list of ipv4 or ipv6 ips to override with, when action is set to dns override
	OverrideIPs []string `json:"override_ips"`

	// host name to override with when action is set to dns override. Can not be used with OverrideIPs
	OverrideHost string `json:"override_host"`

	// settings for l4(network) level overrides
	L4Override *TeamsL4OverrideSettings `json:"l4override"`

	// settings for adding headers to http requests
	AddHeaders http.Header `json:"add_headers"`

	// settings for browser isolation actions
	BISOAdminControls *TeamsBISOAdminControlSettings `json:"biso_admin_controls"`

	// settings for session check in allow action
	CheckSession *TeamsCheckSessionSettings `json:"check_session"`
}

// TeamsL4OverrideSettings used in l4 filter type rule with action set to override.
type TeamsL4OverrideSettings struct {
	IP   string `json:"ip,omitempty"`
	Port int    `json:"port,omitempty"`
}

type TeamsBISOAdminControlSettings struct {
	DisablePrinting  bool `json:"dp"`
	DisableCopyPaste bool `json:"dcp"`
	DisableDownload  bool `json:"dd"`
	DisableUpload    bool `json:"du"`
	DisableKeyboard  bool `json:"dk"`
}

type TeamsCheckSessionSettings struct {
	Enforce  bool     `json:"enforce"`
	Duration Duration `json:"duration"`
}

type TeamsFilterType string

type TeamsGatewayAction string

const (
	HttpFilter TeamsFilterType = "http"
	DnsFilter  TeamsFilterType = "dns"
	L4Filter   TeamsFilterType = "l4"
)

const (
	Allow        TeamsGatewayAction = "allow"
	Block        TeamsGatewayAction = "block"
	SafeSearch   TeamsGatewayAction = "safesearch"
	YTRestricted TeamsGatewayAction = "ytrestricted"
	On           TeamsGatewayAction = "on"
	Off          TeamsGatewayAction = "off"
	Scan         TeamsGatewayAction = "scan"
	NoScan       TeamsGatewayAction = "noscan"
	Isolate      TeamsGatewayAction = "isolate"
	NoIsolate    TeamsGatewayAction = "noisolate"
	Override     TeamsGatewayAction = "override"
	L4Override   TeamsGatewayAction = "l4_override"
)

func TeamsRulesActionValues() []string {
	return []string{
		string(Allow),
		string(Block),
		string(SafeSearch),
		string(YTRestricted),
		string(On),
		string(Off),
		string(Scan),
		string(NoScan),
		string(Isolate),
		string(NoIsolate),
		string(Override),
		string(L4Override),
	}
}

// TeamsRule represents an Teams wirefilter rule.
type TeamsRule struct {
	ID            string             `json:"id,omitempty"`
	CreatedAt     *time.Time         `json:"created_at,omitempty"`
	UpdatedAt     *time.Time         `json:"updated_at,omitempty"`
	DeletedAt     *time.Time         `json:"deleted_at,omitempty"`
	Name          string             `json:"name"`
	Description   string             `json:"description"`
	Precedence    uint64             `json:"precedence"`
	Enabled       bool               `json:"enabled"`
	Action        TeamsGatewayAction `json:"action"`
	Filters       []TeamsFilterType  `json:"filters"`
	Traffic       string             `json:"traffic"`
	Identity      string             `json:"identity"`
	DevicePosture string             `json:"device_posture"`
	Version       uint64             `json:"version"`
	RuleSettings  TeamsRuleSettings  `json:"rule_settings,omitempty"`
}

// TeamsRuleResponse is the API response, containing a single rule.
type TeamsRuleResponse struct {
	Response
	Result TeamsRule `json:"result"`
}

// TeamsRuleResponse is the API response, containing an array of rules.
type TeamsRulesResponse struct {
	Response
	Result []TeamsRule `json:"result"`
}

// TeamsRulePatchRequest is used to patch an existing rule.
type TeamsRulePatchRequest struct {
	ID           string             `json:"id"`
	Name         string             `json:"name"`
	Description  string             `json:"description"`
	Precedence   uint64             `json:"precedence"`
	Enabled      bool               `json:"enabled"`
	Action       TeamsGatewayAction `json:"action"`
	RuleSettings TeamsRuleSettings  `json:"rule_settings,omitempty"`
}

// TeamsRules returns all rules within an account.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsRules(ctx context.Context, accountID string) ([]TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules", accountID)

	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return []TeamsRule{}, err
	}

	var teamsRulesResponse TeamsRulesResponse
	err = json.Unmarshal(res, &teamsRulesResponse)
	if err != nil {
		return []TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRulesResponse.Result, nil
}

// TeamsRule returns the rule with rule ID in the URL.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsRule(ctx context.Context, accountID string, ruleId string) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsCreateRule creates a rule with wirefilter expression.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsCreateRule(ctx context.Context, accountID string, rule TeamsRule) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules", accountID)

	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, rule)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsUpdateRule updates a rule with wirefilter expression.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsUpdateRule(ctx context.Context, accountID string, ruleId string, rule TeamsRule) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, rule)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsPatchRule patches a rule associated values.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsPatchRule(ctx context.Context, accountID string, ruleId string, rule TeamsRulePatchRequest) (TeamsRule, error) {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, rule)
	if err != nil {
		return TeamsRule{}, err
	}

	var teamsRuleResponse TeamsRuleResponse
	err = json.Unmarshal(res, &teamsRuleResponse)
	if err != nil {
		return TeamsRule{}, errors.Wrap(err, errUnmarshalError)
	}

	return teamsRuleResponse.Result, nil
}

// TeamsDeleteRule deletes a rule.
//
// API reference: https://api.cloudflare.com/#teams-rules-properties
func (api *API) TeamsDeleteRule(ctx context.Context, accountID string, ruleId string) error {
	uri := fmt.Sprintf("/accounts/%s/gateway/rules/%s", accountID, ruleId)

	_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package basic

import (
	"github.com/google/gxui"
	"github.com/google/gxui/mixins"
)

func CreateTableLayout(theme *Theme) gxui.TableLayout {
  l := &mixins.TableLayout{}
  l.Init(l, theme)
  return l
}
<commit_msg>Updated gofmt<commit_after>package basic

import (
	"github.com/google/gxui"
	"github.com/google/gxui/mixins"
)

func CreateTableLayout(theme *Theme) gxui.TableLayout {
	l := &mixins.TableLayout{}
	l.Init(l, theme)
	return l
}
<|endoftext|>


<commit_before>// Package rested makes calling RESTful API's easy.
package rested

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

// Request contains parameters to be defined before sending the request to the server. Certain values
// can be omitted based on the request method (i.e. GET typically won't need to send a Body).
type Request struct {
	Method      string
	Query       map[string]string
	ContentType string
	Body        string
	Auth        []string
	Headers     map[string]string
}

// Response contains the information returned from our request.
type Response struct {
	Status  string
	Code    int
	Headers http.Header
	Body    []byte
	Error   error
}

var (
	client = &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
)

// NewRequest creates the state for our REST call.
func NewRequest() *Request {
	return &Request{}
}

// BasicAuth sets the authentication using a standard username/password combination.
func (r *Request) BasicAuth(user, password string) {
	r.Auth = []string{user, password}
}

// Send issues an HTTP request with the given options. "body", "headers" and "query" can be 'nil' if
// you do not need to send the extra data in the request.
func (r *Request) Send(method, uri string, body []byte, headers, query map[string]string) *Response {
	var req *http.Request
	var data Response

	u, err := url.Parse(uri)
	if err != nil {
		data.Error = err

		return &data
	}

	q := u.Query()

	if query != nil {
		for k := range query {
			q.Add(k, query[k])
		}
	}

	u.RawQuery = q.Encode()

	b := bytes.NewReader([]byte(body))
	req, _ = http.NewRequest(strings.ToUpper(method), u.String(), b)

	if len(r.Auth) > 0 {
		req.SetBasicAuth(r.Auth[0], r.Auth[1])
	}

	if headers != nil {
		for k := range headers {
			req.Header.Add(k, headers[k])
		}
	}

	res, err := client.Do(req)
	if err != nil {
		data.Error = err

		return &data
	}

	defer res.Body.Close()

	payload, _ := ioutil.ReadAll(res.Body)
	data.Body = payload
	data.Code = res.StatusCode
	data.Status = res.Status
	data.Headers = res.Header

	if res.StatusCode >= 400 {
		data.Error = fmt.Errorf("HTTP %d: %s", res.StatusCode, string(payload))
	}

	return &data
}

// SendForm is used to send POST/PUT form values when you can't issue the request normally.
// "headers" and "query" can be 'nil' if you do not need to send the extra data in the request.
func (r *Request) SendForm(method, uri string, form, headers, query map[string]string) *Response {
	var req *http.Request
	var data Response

	u, err := url.Parse(uri)
	if err != nil {
		data.Error = err

		return &data
	}

	q := u.Query()

	if query != nil {
		for k := range query {
			q.Add(k, query[k])
		}
	}

	u.RawQuery = q.Encode()

	f := url.Values{}
	for k, v := range form {
		f.Add(k, v)
	}

	req, _ = http.NewRequest(strings.ToUpper(method), u.String(), strings.NewReader(f.Encode()))
	req.PostForm = f
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	if len(r.Auth) > 0 {
		req.SetBasicAuth(r.Auth[0], r.Auth[1])
	}

	if headers != nil {
		for k := range headers {
			req.Header.Add(k, headers[k])
		}
	}

	res, err := client.Do(req)
	if err != nil {
		data.Error = err

		return &data
	}

	defer res.Body.Close()

	payload, _ := ioutil.ReadAll(res.Body)
	data.Body = payload
	data.Code = res.StatusCode
	data.Status = res.Status
	data.Headers = res.Header

	if res.StatusCode >= 400 {
		data.Error = fmt.Errorf("HTTP %d: %s", res.StatusCode, string(payload))
	}

	return &data
}
<commit_msg>Added the ability to post form values<commit_after>// Package rested makes calling RESTful API's easy.
package rested

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	// "strconv"
	"strings"
)

// Request contains parameters to be defined before sending the request to the server. Certain values
// can be omitted based on the request method (i.e. GET typically won't need to send a Body).
type Request struct {
	Method      string
	Query       map[string]string
	ContentType string
	Body        string
	Auth        []string
	Headers     map[string]string
}

// Response contains the information returned from our request.
type Response struct {
	Status  string
	Code    int
	Headers http.Header
	Body    []byte
	Error   error
}

var (
	client = &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
)

// NewRequest creates the state for our REST call.
func NewRequest() *Request {
	return &Request{}
}

// BasicAuth sets the authentication using a standard username/password combination.
func (r *Request) BasicAuth(user, password string) {
	r.Auth = []string{user, password}
}

// Send issues an HTTP request with the given options. To send/post form values, use a map[string]string
// type for the body parameter.
func (r *Request) Send(method, uri string, body interface{}, headers, query map[string]string) *Response {
	var req *http.Request
	var data Response

	u, err := url.Parse(uri)
	if err != nil {
		data.Error = err

		return &data
	}

	q := u.Query()

	if query != nil {
		for k := range query {
			q.Add(k, query[k])
		}
	}

	u.RawQuery = q.Encode()

	switch body.(type) {
	case []byte:
		b := bytes.NewReader(body.([]byte))
		req, _ = http.NewRequest(strings.ToUpper(method), u.String(), b)
	case map[string]string:
		form := url.Values{}
		for k, v := range body.(map[string]string) {
			form.Add(k, v)
		}

		req, _ = http.NewRequest(strings.ToUpper(method), u.String(), strings.NewReader(form.Encode()))
		req.PostForm = form
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}

	if len(r.Auth) > 0 {
		req.SetBasicAuth(r.Auth[0], r.Auth[1])
	}

	if headers != nil {
		for k := range headers {
			req.Header.Add(k, headers[k])
		}
	}

	res, err := client.Do(req)
	if err != nil {
		data.Error = err

		return &data
	}

	defer res.Body.Close()

	payload, _ := ioutil.ReadAll(res.Body)
	data.Body = payload
	data.Code = res.StatusCode
	data.Status = res.Status
	data.Headers = res.Header

	if res.StatusCode >= 400 {
		data.Error = fmt.Errorf("HTTP %d: %s", res.StatusCode, string(payload))
	}

	return &data
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package kafka

import (
	"bytes"

	"github.com/gogo/protobuf/jsonpb"
	"github.com/gogo/protobuf/proto"

	"github.com/jaegertracing/jaeger/model"
)

// Marshaller encodes a span into a byte array to be sent to Kafka
type Marshaller interface {
	Marshal(*model.Span) ([]byte, error)
}

type protobufMarshaller struct{}

func newProtobufMarshaller() *protobufMarshaller {
	return &protobufMarshaller{}
}

// Marshall encodes a span as a protobuf byte array
func (h *protobufMarshaller) Marshal(span *model.Span) ([]byte, error) {
	return proto.Marshal(span)
}

type jsonMarshaller struct {
	pbMarshaller *jsonpb.Marshaler
}

func newJSONMarshaller() *jsonMarshaller {
	return &jsonMarshaller{&jsonpb.Marshaler{}}
}

// Marshall encodes a span as a json byte array
func (h *jsonMarshaller) Marshal(span *model.Span) ([]byte, error) {
	out := new(bytes.Buffer)
	err := h.pbMarshaller.Marshal(out, span)
	return out.Bytes(), err
}
<commit_msg>fix typo (#3609)<commit_after>// Copyright (c) 2018 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package kafka

import (
	"bytes"

	"github.com/gogo/protobuf/jsonpb"
	"github.com/gogo/protobuf/proto"

	"github.com/jaegertracing/jaeger/model"
)

// Marshaller encodes a span into a byte array to be sent to Kafka
type Marshaller interface {
	Marshal(*model.Span) ([]byte, error)
}

type protobufMarshaller struct{}

func newProtobufMarshaller() *protobufMarshaller {
	return &protobufMarshaller{}
}

// Marshal encodes a span as a protobuf byte array
func (h *protobufMarshaller) Marshal(span *model.Span) ([]byte, error) {
	return proto.Marshal(span)
}

type jsonMarshaller struct {
	pbMarshaller *jsonpb.Marshaler
}

func newJSONMarshaller() *jsonMarshaller {
	return &jsonMarshaller{&jsonpb.Marshaler{}}
}

// Marshal encodes a span as a json byte array
func (h *jsonMarshaller) Marshal(span *model.Span) ([]byte, error) {
	out := new(bytes.Buffer)
	err := h.pbMarshaller.Marshal(out, span)
	return out.Bytes(), err
}
<|endoftext|>


<commit_before>package deploystack

import (
	"fmt"
	"os"
	"reflect"
	"testing"

	"github.com/kylelemons/godebug/diff"
)

func TestDomainRegistrarContactYAML(t *testing.T) {
	tests := map[string]struct {
		file    string
		contact ContactData
		err     error
	}{
		"simple": {
			file: "test_files/contact_sample.yaml",
			contact: ContactData{DomainRegistrarContact{
				"you@example.com",
				"+1 555 555 1234",
				PostalAddress{
					"US",
					"94105",
					"CA",
					"San Francisco",
					[]string{"345 Spear Street"},
					[]string{"Your Name"},
				},
			}},
			err: nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			dat, err := os.ReadFile(tc.file)
			if err != nil {
				t.Fatalf("err could not get file for testing: (%s)", err)
			}

			want := string(dat)
			got, err := tc.contact.YAML()

			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if !reflect.DeepEqual(want, got) {
				fmt.Println(diff.Diff(want, got))
				t.Fatalf("expected: \n|%v|\ngot: \n|%v|", want, got)
			}
		})
	}
}

func TestDomainRegistrarContactReadYAML(t *testing.T) {
	tests := map[string]struct {
		file string
		want ContactData
		err  error
	}{
		"simple": {
			file: "test_files/contact_sample.yaml",
			want: ContactData{DomainRegistrarContact{
				"you@example.com",
				"+1 555 555 1234",
				PostalAddress{
					"US",
					"94105",
					"CA",
					"San Francisco",
					[]string{"345 Spear Street"},
					[]string{"Your Name"},
				},
			}},
			err: nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got, err := newContactDataFromFile(tc.file)

			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if !reflect.DeepEqual(tc.want, got) {
				t.Fatalf("expected: %v got: %v", tc.want, got)
			}
		})
	}
}

func TestDomainIsAvailable(t *testing.T) {
	tests := map[string]struct {
		domain    string
		wantAvail string
		wantCost  string
		err       error
	}{
		// TODO: Get this test to work with testing service account.
		// "example.com": {
		// 	domain:    "example.com",
		// 	wantAvail: "UNAVAILABLE",
		// 	wantCost:  "",
		// 	err:       nil,
		// },
		"dsadsahcashfhfdsh.com": {
			domain:    "dsadsahcashfhfdsh.com",
			wantAvail: "AVAILABLE",
			wantCost:  "12USD",
			err:       nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got, err := domainIsAvailable(projectID, tc.domain)
			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if got != nil {

				if !reflect.DeepEqual(tc.wantAvail, got.Availability.String()) {
					t.Fatalf("expected: %v got: %v", tc.wantAvail, got)
				}
				if got.Availability.String() == "AVAILABLE" {
					cost := fmt.Sprintf("%d%s", got.YearlyPrice.Units, got.YearlyPrice.CurrencyCode)
					if !reflect.DeepEqual(tc.wantCost, cost) {
						t.Fatalf("expected: %v got: %v", tc.wantCost, cost)
					}
				}

			}
		})
	}
}

func TestDomainIsVerified(t *testing.T) {
	tests := map[string]struct {
		domain  string
		project string
		want    bool
		err     error
	}{
		"example.com": {
			domain:  "example.com",
			project: projectID,
			want:    false,
			err:     nil,
		},
		"yesornositetester.com": {
			domain:  "yesornositetester.com",
			project: "ds-tester-yesornosite",
			want:    true,
			err:     nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got, err := domainsIsVerified(tc.project, tc.domain)
			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if !reflect.DeepEqual(tc.want, got) {
				t.Fatalf("expected: %v got: %v", tc.want, got)
			}
		})
	}
}
<commit_msg>Killing another flakey test<commit_after>package deploystack

import (
	"fmt"
	"os"
	"reflect"
	"testing"

	"github.com/kylelemons/godebug/diff"
)

func TestDomainRegistrarContactYAML(t *testing.T) {
	tests := map[string]struct {
		file    string
		contact ContactData
		err     error
	}{
		"simple": {
			file: "test_files/contact_sample.yaml",
			contact: ContactData{DomainRegistrarContact{
				"you@example.com",
				"+1 555 555 1234",
				PostalAddress{
					"US",
					"94105",
					"CA",
					"San Francisco",
					[]string{"345 Spear Street"},
					[]string{"Your Name"},
				},
			}},
			err: nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			dat, err := os.ReadFile(tc.file)
			if err != nil {
				t.Fatalf("err could not get file for testing: (%s)", err)
			}

			want := string(dat)
			got, err := tc.contact.YAML()

			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if !reflect.DeepEqual(want, got) {
				fmt.Println(diff.Diff(want, got))
				t.Fatalf("expected: \n|%v|\ngot: \n|%v|", want, got)
			}
		})
	}
}

func TestDomainRegistrarContactReadYAML(t *testing.T) {
	tests := map[string]struct {
		file string
		want ContactData
		err  error
	}{
		"simple": {
			file: "test_files/contact_sample.yaml",
			want: ContactData{DomainRegistrarContact{
				"you@example.com",
				"+1 555 555 1234",
				PostalAddress{
					"US",
					"94105",
					"CA",
					"San Francisco",
					[]string{"345 Spear Street"},
					[]string{"Your Name"},
				},
			}},
			err: nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got, err := newContactDataFromFile(tc.file)

			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if !reflect.DeepEqual(tc.want, got) {
				t.Fatalf("expected: %v got: %v", tc.want, got)
			}
		})
	}
}

func TestDomainIsAvailable(t *testing.T) {
	tests := map[string]struct {
		domain    string
		wantAvail string
		wantCost  string
		err       error
	}{
		// TODO: Get this test to work with testing service account.
		// "example.com": {
		// 	domain:    "example.com",
		// 	wantAvail: "UNAVAILABLE",
		// 	wantCost:  "",
		// 	err:       nil,
		// },
		"dsadsahcashfhfdsh.com": {
			domain:    "dsadsahcashfhfdsh.com",
			wantAvail: "AVAILABLE",
			wantCost:  "12USD",
			err:       nil,
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got, err := domainIsAvailable(projectID, tc.domain)
			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if got != nil {

				if !reflect.DeepEqual(tc.wantAvail, got.Availability.String()) {
					t.Fatalf("expected: %v got: %v", tc.wantAvail, got)
				}
				if got.Availability.String() == "AVAILABLE" {
					cost := fmt.Sprintf("%d%s", got.YearlyPrice.Units, got.YearlyPrice.CurrencyCode)
					if !reflect.DeepEqual(tc.wantCost, cost) {
						t.Fatalf("expected: %v got: %v", tc.wantCost, cost)
					}
				}

			}
		})
	}
}

func TestDomainIsVerified(t *testing.T) {
	tests := map[string]struct {
		domain  string
		project string
		want    bool
		err     error
	}{
		"example.com": {
			domain:  "example.com",
			project: projectID,
			want:    false,
			err:     nil,
		},
		// TODO: Get this test to work with testing service account.
		// "yesornositetester.com": {
		// 	domain:  "yesornositetester.com",
		// 	project: "ds-tester-yesornosite",
		// 	want:    true,
		// 	err:     nil,
		// },
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got, err := domainsIsVerified(tc.project, tc.domain)
			if err != tc.err {
				if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
					t.Fatalf("expected: error(%s) got: error(%s)", tc.err, err)
				}
			}

			if !reflect.DeepEqual(tc.want, got) {
				t.Fatalf("expected: %v got: %v", tc.want, got)
			}
		})
	}
}
<|endoftext|>