text:
Hacking on OpenShift
====================

## Building a Release

To build an OpenShift release you run the `hack/build-release.sh` script on a
system with Docker, which will create a build environment image and then
execute a cross platform Go build within it. The build output will be copied
to `_output/releases` as a set of tars containing each version. It will also
build the `openshift/origin-base` image which is the common parent image for all
OpenShift Docker images.

    $ make release

NOTE:  Only committed code is built.

To build the base and release images, run:

    $ hack/build-base-images.sh

Today, all of our container image builds require
[imagebuilder](https://github.com/openshift/imagebuilder).

Once a release has been created, it can be pushed:

    $ hack/push-release.sh

To cut an official tag release, we generally use the images built by
[ci.openshift.redhat.com](https://ci.openshift.redhat.com)
under the devenv_ami job.

1. Create a new git tag `git tag vX.X.X -a -m "vX.X.X" HEAD`
2. Push the tag to GitHub `git push origin --tags` where `origin` is
`github.com/openshift/origin.git`
3. Run the "devenv_ami" job
4. Once the images are pushed to the repository, run `OS_PUSH_TAG="vX.X.X"
hack/push-release.sh`. Your tag must match the Git tag.
5. Upload the binary artifacts generated by that build to GitHub release page
6. Send an email to the dev list, including the important changes prior to the
release.

We generally cut a release before disruptive changes land.

## Test Suites

OpenShift uses three levels of testing - unit tests, integration test, and
end-to-end tests (much like Kubernetes).

### Unit tests

Unit tests follow standard Go conventions and are intended to test the behavior
and output of a single package in isolation. All code is expected to be easily
testable with mock interfaces and stubs, and when they are not it usually means
that there's a missing interface or abstraction in the code. A unit test should
focus on testing that branches and error conditions are properly returned and
that the interface and code flows work as described. Unit tests can depend
on other packages but should not depend on other components (an API test should
not be writing to etcd).

The unit tests for an entire package should not take more than 0.5s to run, and
if they do, are probably not really unit tests or need to be rewritten to avoid
sleeps or pauses. Coverage on a unit test should be above 70% unless the units
are a special case.

See `pkg/template/generator` for examples of unit tests. Unit tests should
follow Go conventions.

Run the unit tests with:

    $ hack/test-go.sh

or an individual package using its relative path with:

    $ hack/test-go.sh pkg/build

or an individual package and all packages nested under it:

    $ hack/test-go.sh pkg/build/...

To run only a certain regex of tests in a package, use:

    $ hack/test-go.sh pkg/build -test.run=SynchronizeBuildRunning

To get verbose output for the above example:

    $ hack/test-go.sh pkg/build -test.run=SynchronizeBuildRunning -v

To run all tests with verbose output:

    $ hack/test-go.sh -v

To change the timeout for individual unit tests, which defaults to one minute,
use:

    $ TIMEOUT=<timeout> hack/test-go.sh

To enable running the kubernetes unit tests:

    $ TEST_KUBE=true hack/test-go.sh

To run unit test for an individual kubernetes package:

    $ hack/test-go.sh vendor/k8s.io/kubernetes/examples

To change the coverage mode, which is `-cover -covermode=atomic` by default,
use:

    $ COVERAGE_SPEC="<some coverage specification>" hack/test-go.sh

To turn off coverage calculation, which is on by default, use:

    $ COVERAGE_SPEC= hack/test-go.sh

To run tests without the go race detector, which is on by default, use:

    $ DETECT_RACES= hack/test-go.sh

To create a line coverage report, set `OUTPUT_COVERAGE` to a path where the
report should be stored. For example:

    $ COVERAGE_OUTPUT_DIR='/path/to/dir' hack/test-go.sh

After that you can open `/path/to/dir/coverage.html` in the browser.

To generate a jUnit XML report from the output of the tests, and see a summary
of the test output instead of the full test output, use:

    $ JUNIT_REPORT=true hack/test-go.sh

`hack/test-go.sh` cannot generate jUnit XML and a coverage report for all
packages at once. If you require both, you must call `hack/test-go.sh` twice.

### Integration tests

Integration tests cover multiple components acting together (generally, 2 or
3). These tests should focus on ensuring that naturally related components work
correctly.  They should not be extensively testing branches or error conditions
inside packages (that's what unit tests do), but they should validate that
important success and error paths work across layers (especially when errors
are being converted from lower level errors). Integration tests should not be
testing details of the inter-component connections - API tests should not test
that the JSON serialized to the wire is correctly converted back and forth (unit test
responsibility), but they should test that those connections have the expected
outcomes. The underlying goal of integration tests is to wire together the most
important components in isolation. Integration tests should be as fast as possible
in order to enable them to be run repeatedly during testing.  Integration tests
that take longer than 0.5s are probably trying to test too much together and
should be reorganized into separate tests.  Integration tests should generally
be written so that they are starting from a clean slate, but if that involves
costly setup those components should be tested in isolation.

We break integration tests into two categories, those that use Docker and those
that do not.  In general, high-level components that depend on the behavior of code
running inside a Docker container should have at least one or two integration tests
that test all the way down to Docker, but those should be part of their own
test suite.  Testing the API and high level API functions should generally
not depend on calling into Docker. They are denoted by special test tags and
should be in their own files so we can selectively build them.

All integration tests are located under `test/integration/*`. All integration
tests must set the `integration` build tag at the top of their source file,
and also declare whether they need etcd with the `etcd` build tag and whether
they need Docker with the `docker` build tag. For special function sets please
create sub directories like `test/integration/deployimages`.

Run the integration tests with:

    $ hack/test-integration.sh

The script launches an instance of etcd and then invokes the integration tests.
If you need to execute a subset of integration tests, run:

    $ hack/test-integration.sh <regex>

Where `<regex>` is some regular expression that matches the names of all
of the tests you want to run. The regular expression is passed into `grep -E`,
so ensure that the syntax or features you use are supported. The default
regular expression used
is `Test`, which matches all tests.

Each integration function is executed in its own process so that it cleanly
shuts down any background
goroutines. You will not be able to run more than a single test within a single
process.

There is a CLI integration test suite which covers general non-Docker
functionality of the CLI tool
working against the API. Run it with:

    $ hack/test-cmd.sh

This suite comprises many smaller suites, which are found under `test/cmd` and
can be run individually by specifying a regex filter, passed through `grep -E`
like with integration tests above:

    $ hack/test-cmd.sh <regex>

During development, you can run a file `test/cmd/*.sh` directly to test against
a running server. This can speed up the feedback loop considerably. All
`test/cmd/*` tests are expected
to be executable repeatedly - please file bugs if a test needs cleanup before
running.

For example, start the OpenShift server, create a "test" project, and then run
`oc new-app` tests against the server:

    $ oc new-project test
    $ test/cmd/newapp.sh

In order to run the suite, generate a jUnit XML report, and see a summary of
the test suite, use:

    $ JUNIT_REPORT='true' hack/test-cmd.sh

### End-to-End (e2e) and Extended Tests

The final test category is end to end tests (e2e) which should verify a long
set of flows in the product as a user would see them.  Two e2e tests should not
overlap more than 10% of function, and are not intended to test error conditions
in detail. The project
examples should be driven by e2e tests. e2e tests can also test external
components working together.

The end-to-end suite is currently implemented primarily in Bash, but will be
folded into the extended suite (located in test/extended) over time.
The extended suite is closer to the upstream Kubernetes e2e suite and
tests the full behavior of a running system.

Run the end to end tests with:

    $ hack/test-end-to-end.sh

Run the extended tests with:

    $ test/extended/core.sh

This suite comprises many smaller suites, which are found under `test/extended`
and can be run individually by specifying `--ginkgo.focus` and a regex filter:

    $ test/extended/core.sh --ginkgo.focus=<regex>

In addition, the extended tests can be ran against an existing OpenShift
cluster:

    $ KUBECONFIG=/path/to/admin.kubeconfig TEST_ONLY=true test/extended/core.sh --ginkgo.focus=<regex>

Extended tests should be Go tests in the `test/extended` directory that use
the Ginkgo library. They must be able to be run remotely, and cannot depend on
any local interaction with the filesystem or Docker.

More information about running extended tests can be found in
[test/extended/README](https://github.com/openshift/origin/blob/master/test/extended/README.md).

## Installing Godep

OpenShift and Kubernetes use [Godep](https://github.com/tools/godep) for
dependency management.  Godep allows versions of dependent packages to be
locked at a specific commit by *vendoring* them (checking a copy of them into
`vendor/`).
This means that everything you need for OpenShift is checked into this
repository.

To install `godep` locally run:

    $ go get github.com/tools/godep

If you are not updating packages you should not need godep installed.

## Cherry-picking an upstream commit into Origin: Why, how, and when.

Origin carries patches inside of vendor/ on top of each rebase.
Thus, origin carries upstream patches in two ways.

1. *periodic rebases* against a Kubernetes commit.
Eventually, any code you have in upstream kubernetes will land in Openshift
via this mechanism.

2. Cherry-picked patches for important *bug fixes*.  We really try to
limit feature back-porting entirely.

### Manually

You can manually try to cherry pick a commit (by using git apply). This can
easily be done in a couple of steps.

- wget the patch, i.e. `wget -O /tmp/mypatch
https://github.com/kubernetes/kubernetes/pull/34624.patch`
- PATCH=/tmp/mypatch git apply --directory vendor/k8s.io/kubernetes $PATCH

If this fails, then it's possible you may need to pick multiple commits.

### For Openshift newcomers: Pick my kubernetes fix into Openshift vs. wait for
the next rebase?

Assuming you read the bullets above... If your patch is really far behind, for
example, if there have been 5 commits modifying the directory you care about,
cherry picking will be increasingly difficult and you should consider waiting
for the next rebase, which will likely include the commit you care about, or at
least decrease the amount of cherry picks you need to do to merge.

To really know the answer, you need to know *how many commits behind you are in
a particular directory*, often.

To do this, just use git log, like so (using pkg/scheduler/ as an example).

```
MYDIR=pkg/scheduler/algorithm git log --oneline --
vendor/k8s.io/kubernetes/${MYDIR} | grep UPSTREAM | cut -d' ' -f 4-10 | head -1
```

The commit message printed above will tell you:

- what the LAST commit in Kubernetes was (which effected
"/pkg/scheduler/algorithm")
- directory, which will give you an intuition about how "hot" the code you are
cherry picking is.  If it has changed a lot, recently, then that means you
probably will want to wait for a rebase to land.

### Using hack/cherry-pick

For convenience, you can use `hack/cherry-pick.sh` to generate patches for
Origin from upstream commits.

The purpose of this command is to allow you to pull individual commits from a
local kubernetes repository into origin's vendored kuberenetes in a fully
automated manner.

To use this command, be sure to setup remote Pull Request branches in the
kubernetes repository you are using (i.e. like https://gist.github.com/piscisaureus/3342247).
Specifically, you will be doing this, to the git config you probably already
have for kubernetes:

```
[remote "origin"]
        url = https://github.com/kubernetes/kubernetes
        fetch = +refs/heads/*:refs/remotes/origin/*
	### Add this line
        fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
```

so that `git show origin/pr/<number>` displays information about your branch
after a `git fetch`.

You must also have the Kubernetes repository checked out in your GOPATH
(visible as `../../../k8s.io/kubernetes`),
with openshift/kubernetes as a remote and fetched:

    $ pushd $GOPATH/src/k8s.io/kubernetes
    $ git remote add openshift https://github.com/openshift/kubernetes.git
    $ git fetch openshift
    $ popd

There must be no modified or uncommitted files in either repository.

To pull an upstream commit, run:

    $ hack/cherry-pick.sh <pr_number>

This will attempt to create a patch from the current Kube rebase version in
Origin that contains the commits added in the PR. If the PR has already been
merged to the Kube version, you'll get an error. If there are conflicts, you'll
have to resolve them in the upstream repo, then hit ENTER to continue. The end
result will be a single commit in your Origin repo that contains the changes.

If you want to run without a rebase option, set `NO_REBASE=1` before the
command is run. You can also specify a commit range directly with:

    $ hack/cherry-pick.sh origin/master...<some_branch>

All upstream commits should have a commit message where the first line is:

    UPSTREAM: <PR number|drop|carry>: <short description>

`drop` indicates the commit should be removed during the next rebase. `carry`
means that the change cannot go into upstream, and we should continue to use it
during the next rebase.

You can also target repositories other than Kube by setting `UPSTREAM_REPO` and
`UPSTREAM_PACKAGE` env vars.  `UPSTREAM_REPO` should be the full name of the Git
repo as Go sees it, i.e. `github.com/coreos/etcd`, and `UPSTREAM_PACKAGE` must be
a package inside that repo that is currently part of the Godeps.json file.  Example:

    $ UPSTREAM_REPO=github.com/coreos/etcd UPSTREAM_PACKAGE=store
hack/cherry-pick.sh <pr_number>

By default `hack/cherry-pick.sh` uses git remote named `origin` to fetch
kubernetes repository, if your git configuration is different, you can pass the git
remote name by setting `UPSTREAM_REMOTE` env var:

    $ UPSTREAM_REMOTE=upstream hack/cherry-pick.sh <pr_number>

## Moving a commit you developed in Origin to an upstream

The `hack/move-upstream.sh` script takes the current feature branch, finds any
changes to the
requested upstream project (as defined by `UPSTREAM_REPO` and
`UPSTREAM_PACKAGE`) that differ from `origin/master`, and then creates a new
commit in that upstream project on a branch with the same name as your current
branch.

For example, to upstream a commit to OpenShift source-to-image while working
from Origin:

    $ git checkout my_feature_branch_in_origin
    $ git log --oneline
    70ffe7e Docker and STI builder support binary extraction
    75a22de UPSTREAM: <sti>: Allow prepared directories to be passed to STI
    86eefdd UPSTREAM: 14618: Refactor exec to allow reuse from server

    # we want to move our STI changes to upstream
    $ UPSTREAM_REPO=github.com/openshift/source-to-image
UPSTREAM_PACKAGE=pkg/api hack/move-upstream.sh
    ...

    # All changes to source-to-image in Godeps/. are now in a commit UPSTREAMED
in s2i repo

    $ cd ../source-to-image
    $ git log --oneline
    c0029f6 UPSTREAMED
    ... # older commits

The default is to work against Kube.
go

## Updating Kubernetes from upstream

There are a few steps involved in rebasing Origin to a new version of
Kubernetes. We need to make sure
that not only the Kubernetes packages were updated correctly into `Godeps`, but
also that *all tests are
still running without errors* and *code changes, refactorings or the
inclusion/removal of attributes
were properly reflected* in the Origin codebase.

### 1. Preparation

Before you begin, make sure you have both
[openshift/origin](https://github.com/openshift/origin) and
[kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) in your
$GOPATH. You may want to work
on a separate $GOPATH just for the rebase:

```
$ go get github.com/openshift/origin
$ go get k8s.io/kubernetes
```

You must add the Origin GitHub fork as a remote in your k8s.io/kubernetes repo:

```
$ cd $GOPATH/src/k8s.io/kubernetes
$ git remote add openshift git@github.com:openshift/kubernetes.git
$ git fetch openshift
```

Check out the version of Kubernetes you want to rebase as a branch or tag named
`stable_proposed` in
[kubernetes/kubernetes](https://github.com/kubernetes/kubernetes). For example,
if you are going to rebase the latest `master` of Kubernetes:

```
$ cd $GOPATH/src/k8s.io/kubernetes
$ git checkout master
$ git pull
$ git checkout -b stable_proposed
```

### 2. Rebase Origin to the new Kubernetes version

#### 2.1. First option (preferred): using the rebase-kube.sh script

If all requirements described in *Preparation* were correctly attended, you
should not have any trouble with rebasing the Kubernetes code using the script
that automates this process.

```
$ cd $GOPATH/src/github.com/openshift/origin
$ hack/rebase-kube.sh
```

Read over the changes with `git status` and make sure it looks reasonable.
Check specially the `Godeps/Godeps.json` file to make sure no dependency
is unintentionally missing.

Commit using the message `bump(k8s.io/kubernetes):<commit SHA>`, where
`<commit SHA>` is the commit id for the Kubernetes version we are including in
our Godeps. It can be found in our `Godeps/Godeps.json` in the declaration of
any Kubernetes package.

#### 2.2. Second option: manually

If for any reason you had trouble rebasing using the script, you may need to to
do it manually.
After following all requirements described in the *Preparation* topic, you will
need to run
`godep restore` from both the Origin and the Kubernetes directories and then
`godep save ./...`
from the Origin directory. Follow these steps:

1. `$ cd $GOPATH/src/github.com/openshift/origin`
2. `make clean ; godep restore` will restore the package versions specified in
the `Godeps/Godeps.json` of Origin to your GOPATH.
2. `$ cd $GOPATH/src/k8s.io/kubernetes`
3. `$ git checkout stable_proposed` will checkout the desired version of
Kubernetes as branched in *Preparation*.
4. `$ godep restore` will restore the package versions specified in the
`Godeps/Godeps.json` of Kubernetes to your GOPATH.
5. `$ cd $GOPATH/src/github.com/openshift/origin`.
6. `$ make clean ; godep save ./...` will save a list of the checked-out
dependencies to the file `Godeps/Godeps.json`, and copy their source code into `vendor`.
7. If in the previous step godep complaints about the checked out revision of a
package being different  than the wanted revision, this probably means there are
new packages in Kubernetes that we need to add.  Do a `godep save <pkgname>` with
the package specified by the error message and then `$ godep save ./...`
again.
8. Read over the changes with `git status` and make sure it looks reasonable.
Check specially the `Godeps/Godeps.json` file to make sure no dependency is
unintentionally missing. The whole Godeps directory will be added to version control, including
`_workspace`.
9. Commit using the message `bump(k8s.io/kubernetes):<commit SHA>`, where
`<commit SHA>` is the commit id for the Kubernetes version we are including in
our Godeps. It can be found in our `Godeps/Godeps.json` in the declaration of
any Kubernetes package.

If in the process of rebasing manually you found any corner case not attended
by the `hack/rebase-kube.sh` script, make sure you update it accordingly to help future rebases.

### 3. cherry-pick upstream changes pushed to the Origin repo

Eventually during the development cycle we introduce changes to dependencies
right in the Origin
repository. This is not a largely recommended practice, but it's useful if we
need something that,
for example, is in the Kubernetes repository but we are not doing a rebase yet.
So, when doing the next
rebase, we need to make sure we get all these changes otherwise they will be
overridden by `godep save`.

1. Check the `Godeps` directory [commits
history](https://github.com/openshift/origin/commits/master/Godeps)
for commits tagged with the *UPSTREAM* keyword. We will need to cherry-pick
*all UPSTREAM commits since
the last Kubernetes rebase* (remember you can find the last rebase commit
looking for a message like
`bump(k8s.io/kubernetes):...`).
2. For every commit tagged UPSTREAM, do `git cherry-pick <commit SHA>`.
3. Notice that eventually the cherry-pick will be empty. This probably means
the given change were
already merged in Kubernetes and we don't need to specifically add it to our
Godeps. Nice!
4. Read over the commit history and make sure you have every UPSTREAM commit
since the last rebase
(except only for the empty ones).

### 4. Refactor Origin to be compliant with upstream changes

After making sure we have all the dependencies in place and up-to-date, we need
to work in the Origin
codebase to make sure the compilation is not broken, all tests pass and it's
compliant with any refactorings, architectural changes or behavior changes
introduced in Kubernetes. Make sure:

1. `make clean ; hack/build-go.sh` compiles without errors and the standalone
server starts correctly.
1. all of our generated code is up to date by running all `hack/update-*`
scripts.
1. `hack/verify-open-ports.sh` runs without errors.
1. `hack/copy-kube-artifacts.sh` so Kubernetes tests can be fully functional.
The diff resulting from this script should be squashed into the Kube bump
commit.
2. `TEST_KUBE=1 hack/test-go.sh` runs without errors.
3. `hack/test-cmd.sh` runs without errors.
3. `hack/test-integration.sh` runs without errors.
3. `hack/test-end-to-end.sh` runs without errors.
    See *Building a Release* above for setting up the environment for the
*test-end-to-end.sh* tests.

It is helpful to look at the Kubernetes commit history to be aware of the major
topics. Although it
can potentially break or change any part of Origin, the most affected parts are
usually:

1. https://github.com/openshift/origin/blob/master/pkg/cmd/server/start
2.
https://github.com/openshift/origin/blob/master/pkg/cmd/server/kubernetes/master
.go
3.
https://github.com/openshift/origin/blob/master/pkg/cmd/server/origin/master.go
4.
https://github.com/openshift/origin/blob/master/pkg/cmd/util/clientcmd/factory.g
o
5. https://github.com/openshift/origin/blob/master/pkg/cmd/cli/cli.go
6. https://github.com/openshift/origin/blob/master/pkg/api/meta/meta.go

Place all your changes in a commit called "Refactor to match changes upstream".

### 5. Pull request

A typical pull request for your Kubernetes rebase will contain:

1. One commit for the Kuberentes Godeps bump (`bump(k8s.io/kubernetes):<commit
SHA>`).
2. Zero, one, or more bump commits for any **shared** dependencies between
Origin and Kubernetes that have been bumped. Any transitive dependencies coming
from Kubernetes should be squashed in the Kube bump commit.
3. Zero, one, or more cherry-picked commits tagged UPSTREAM.
4. One commit "Boring refactor to match changes upstream" that includes boring
changes like imports rewriting, etc.
5. One commit "Interesting refactor to match changes upstream" that includes
interesting changes like new plugins or controller changes.

## Updating other Godeps from upstream

To update to a new version of a dependency that's not already included in
Kubernetes, checkout the correct version in your GOPATH and then run
`godep save <pkgname>`.  This should create a new version of `Godeps/Godeps.json`,
and update `vendor`.  Create a commit that includes both of these changes with message
`bump(<pkgname>): <pkgcommit>`.

## Updating external examples

`hack/update-external-example.sh` will pull down example files from external
repositories and deposit them under the `examples` directory.
Run this script if you need to refresh an example file, or add a new one.  See
the script and `examples/quickstarts/README.md` for more details.

## Troubleshooting

If you run into difficulties running OpenShift, start by reading through the
[troubleshooting
guide](https://github.com/openshift/origin/blob/master/docs/debugging-openshift.
md).

## RPM Packaging

A specfile is included in this repo which can be used to produce RPMs including
the openshift binary. While the specfile will be kept up to date with build
requirements the version is not updated. You will need to either update the
Version, %commit, and %ldflags values on your own or you may use
[tito](https://github.com/dgoodwin/tito) to build
and tag releases.

## GSSAPI-enabled builds

When built with GSSAPI support, the `oc` client supports logging in with
Kerberos credentials on Linux and OS X.
GSSAPI-enabled builds of `oc` cannot be cross-compiled, but must be built on
the target platform with the GSSAPI header files available.

On Linux, ensure the `krb5-devel` package is installed:

    $ sudo yum install -y krb5-devel

On OS X, you can obtain header files via Homebrew:

    $ brew install homebrew/dupes/heimdal --without-x11

Once dependencies are in place, build with the `gssapi` tag:

    $ hack/build-go.sh cmd/oc -tags=gssapi

Verify that the GSSAPI feature is enabled with `oc version`:

    $ oc version
    ...
    features: Basic-Auth GSSAPI Kerberos SPNEGO

## Swagger API Documentation

OpenShift and Kubernetes integrate with the [Swagger 2.0 API
framework](http://swagger.io) which aims to make it easier to document and
write clients for RESTful APIs.  When you start OpenShift, the Swagger API
endpoint is exposed at `https://localhost:8443/swaggerapi`. The Swagger UI
makes it easy to view your documentation - to view the docs for your local
version of OpenShift start the server with CORS enabled:

    $ openshift start --cors-allowed-origins=.*

and then browse to http://openshift3swagger-claytondev.rhcloud.com (which runs
a copy of the Swagger UI that points to localhost:8080 by default).  Expand the
operations available on v1 to see the schemas (and to try the API directly).
Additionally, you can download swagger-ui from http://swagger.io/swagger-ui/
and use it to point to your local swagger API endpoint.

Note: Hosted API documentation can be found
[here](http://docs.openshift.org/latest/rest_api/openshift_v1.html).

## Performance debugging

OpenShift integrates the go `pprof` tooling to make it easy to capture CPU and
heap dumps for running systems.  The following modes are available for the
`openshift` binary (including all the CLI variants):

* `OPENSHIFT_PROFILE` environment variable:
  * `cpu` - will start a CPU profile on startup and write `./cpu.pprof`.
Contains samples for the entire run at the native sampling resolution (100hz).
Note: CPU profiling for Go does not currently work on Mac OS X - the stats are
not correctly sampled
  * `mem` - generate a running heap dump that tracks allocations to
`./mem.pprof`
  * `block` -  will start a block wait time analysis and write `./block.pprof`
  * `web` - start the pprof webserver in process at http://127.0.0.1:6060/debug/pprof
(you can open this in a browser). This supports `OPENSHIFT_PROFILE_HOST=`
and `OPENSHIFT_PROFILE_PORT=` to change default ip `127.0.0.1` and default port `6060`.

In order to start the server in CPU profiling mode, run:

    $ OPENSHIFT_PROFILE=cpu sudo ./_output/local/bin/linux/amd64/openshift start

Or, if running OpenShift under systemd, append this to
`/etc/sysconfig/atomic-openshift-{master,node}`

    OPENSHIFT_PROFILE=cpu

To view profiles, you use
[pprof](http://goog-perftools.sourceforge.net/doc/cpu_profiler.html) which is
part of `go tool`.  You must pass the binary you are debugging (for symbols)
and a captured pprof.  For instance, to view a `cpu` profile from above, you
would run OpenShift to completion, and then run:

    $ go tool pprof ./_output/local/bin/linux/amd64/openshift cpu.pprof
    or
    $ go tool pprof $(which openshift) /var/lib/origin/cpu.pprof

This will open the `pprof` shell, and you can then run:

    # see the top 20 results
    (pprof) top20

    # see the top 50 results
    (pprof) top50

    # show the top20 sorted by cumulative time
    (pprof) cum=true
    (pprof) top20

to see the top20 CPU consuming fields or

    (pprof) web

to launch a web browser window showing you where CPU time is going.

`pprof` supports CLI arguments for looking at profiles in different ways -
memory profiles by default show allocated space:

    $ go tool pprof ./_output/local/bin/linux/amd64/openshift mem.pprof

but you can also see the allocated object counts:

    $ go tool pprof --alloc_objects ./_output/local/bin/linux/amd64/openshift
mem.pprof

Finally, when using the `web` profile mode, you can have the go tool directly
fetch your profiles via HTTP:

    # for a 30s CPU trace
    $ go tool pprof ./_output/local/bin/linux/amd64/openshift
http://127.0.0.1:6060/debug/pprof/profile

    # for a snapshot heap dump at the current time, showing total allocations
    $ go tool pprof --alloc_space ./_output/local/bin/linux/amd64/openshift
http://127.0.0.1:6060/debug/pprof/heap

See [debugging Go programs](https://golang.org/pkg/net/http/pprof/) for more
info.  `pprof` has many modes and is very powerful (try `tree`) - you can pass
a regex to many arguments to limit your results to only those samples that
match the regex (basically the function name or the call stack).


text:
class CreateLocations < ActiveRecord::Migration
  def change
    create_table :locations do |t|
      t.string :country
      t.string :country_code, limit: 3
      t.timestamps
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
package VMOMI::ClusterVmHostRuleInfo;
use parent 'VMOMI::ClusterRuleInfo';

use strict;
use warnings;

our @class_ancestors = (
    'ClusterRuleInfo',
    'DynamicData',
);

our @class_members = (
    ['vmGroupName', undef, 0, 1],
    ['affineHostGroupName', undef, 0, 1],
    ['antiAffineHostGroupName', undef, 0, 1],
);

sub get_class_ancestors {
    return @class_ancestors;
}

sub get_class_members {
    my $class = shift;
    my @super_members = $class->SUPER::get_class_members();
    return (@super_members, @class_members);
}

1;


text:
package org.jasig.cas.authentication.principal;

import java.util.Collections;
import java.util.Map;

import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.util.Assert;

/**
 * Simple implementation of a AttributePrincipal that exposes an unmodifiable
 * map of attributes.
 *
 * @author Scott Battaglia
 * @author Marvin S. Addison
 * @since 3.1
 */
public class SimplePrincipal implements Principal {
    /** Serialization support. */
    private static final long serialVersionUID = -1255260750151385796L;

    /** The unique identifier for the principal. */
    private final String id;

    /** Map of attributes for the Principal. */
    private Map<String, Object> attributes;

    /** No-arg constructor for serialization support. */
    private SimplePrincipal() {
        this.id = null;
    }

    public SimplePrincipal(final String id) {
        this(id, null);
    }

    public SimplePrincipal(final String id, final Map<String, Object> attributes) {
        Assert.notNull(id, "id cannot be null");
        this.id = id;
        this.attributes = attributes;
    }

    /**
     * @return An immutable map of principal attributes
     */
    public Map<String, Object> getAttributes() {
        return this.attributes == null
                ? Collections.<String, Object>emptyMap()
                : Collections.unmodifiableMap(this.attributes);
    }

    public String toString() {
        return this.id;
    }

    public int hashCode() {
        final HashCodeBuilder builder = new HashCodeBuilder(83, 31);
        builder.append(this.id);
        return builder.toHashCode();
    }

    public final String getId() {
        return this.id;
    }

    public boolean equals(final Object o) {
        return o instanceof SimplePrincipal && ((SimplePrincipal) o).getId().equals(this.id);
    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
Uses of Class edu.american.student.stonewall.display.html.component.HTMLObject
</TITLE>

<META NAME="date" CONTENT="2013-03-25">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../../stylesheet.css" TITLE="Style">

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes

Uses of Class
edu.american.student.stonewall.display.html.component.HTMLObject

Packages that use HTMLObject

edu.american.student.stonewall.display.html.component

Uses of HTMLObject in edu.american.student.stonewall.display.html.component

Methods in edu.american.student.stonewall.display.html.component that return HTMLObject

 HTMLObject
HTMLObject.setFormIDs(java.lang.String... ids)

          The form attribute specifies one or more forms the object element
 belongs to.

 Example:form="myform"

 Implementation:NONE

 HTMLObject
HTMLObject.setHeight(int height)

          The height attribute specifies the height of the object, in pixels.

 Example:height = "300"

 Implementation:IE,Firefox,Opera,Chrome,Safari

 HTMLObject
HTMLObject.setMap(java.lang.String mapID)

          The usemap attribute specifies the name of an image-map to use with the
 object.

 An image-map is an image with clickable areas.

 The usemap attribute is associated with a map element's name attribute,
 and creates a relationship between the object and the map.

 Example:usemap="#planetMap"

 Implementation:IE,Firefox,Opera

 HTMLObject
HTMLObject.setMIMEType(java.lang.String type)

          The type attribute specifies the MIME type of the object.

 Example:type="application/x-shockwave-flash"

 Implementation:IE,Firefox,Opera,Chrome,Safari

 HTMLObject
HTMLObject.setName(java.lang.String name)

          The name attribute specifies the name of an object element.

 HTMLObject
HTMLObject.setSource(ResourceFinder source)

          The data attribute specifies the URL of the resource to be used by the
 object.

 Example:data="helloworld.swf"

 Implementation:IE,Firefox,Opera,Chrome,Safari

 HTMLObject
HTMLObject.setWidth(int width)

          The width attribute specifies the width of the object, in pixels.

 Example:width="500"

 Implementation:IE,Firefox,Opera,Chrome,Safari

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes


text:
class Wire
  attr_accessor :type
  attr_reader :color

  def initialize(color)
    @color = color
    @state = :intact
  end

  def cut?
    @state == :cut
  end

  def intact?
    @state == :intact
  end

  def is_type?(type)
    @type == type
  end

  def snip
    raise RuntimeError, "Wire is already cut." if cut?

    @state = :cut
  end
end


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Bull. Torrey bot. Club 48: 41 (1921)

#### Original name
Puccinia suksdorfii Ellis & Everh.

### Remarks
null


text:
using System;
using System.IO;

using System.Net; // WebPermission.
using System.Security;
using System.Security.Permissions;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Navigation;
using MS.Internal.Controls;
using MS.Internal.Navigation;
using MS.Internal.Utility;
using MS.Internal.Resources;
using System.IO.Packaging;
using MS.Internal.PresentationFramework;
using System.ComponentModel;
using System.Windows.Controls;

namespace MS.Internal.AppModel
{
    // !!!! Note: Those methods are registered as MimeObjectFactory.StreamToObjectFactoryDelegate. The caller expects the
    // delgate to close stream.
    internal static class AppModelKnownContentFactory
    {
        // <summary>
        // Creates an object instance from a Baml stream and it's Uri
        // </summary>
        internal static object BamlConverter(Stream stream, Uri baseUri, bool canUseTopLevelBrowser, bool sandboxExternalContent, bool allowAsync, bool isJournalNavigation, out XamlReader asyncObjectConverter)
        {
            asyncObjectConverter = null;

            // If this stream comes from outside the application throw
            //
            if (!BaseUriHelper.IsPackApplicationUri(baseUri))
            {
                throw new InvalidOperationException(SR.Get(SRID.BamlIsNotSupportedOutsideOfApplicationResources));
            }

            // If this stream comes from a content file also throw
            Uri partUri = PackUriHelper.GetPartUri(baseUri);
            string partName, assemblyName, assemblyVersion, assemblyKey;
            BaseUriHelper.GetAssemblyNameAndPart(partUri, out partName, out assemblyName, out assemblyVersion, out assemblyKey);
            if (ContentFileHelper.IsContentFile(partName))
            {
                throw new InvalidOperationException(SR.Get(SRID.BamlIsNotSupportedOutsideOfApplicationResources));
            }

            ParserContext pc = new ParserContext();

            pc.BaseUri = baseUri;
            pc.SkipJournaledProperties = isJournalNavigation;

            return Application.LoadBamlStreamWithSyncInfo(stream, pc);
        }

        // <summary>
        // Creates an object instance from a Xaml stream and it's Uri
        // </summary>
        ///<SecurityNote>
        /// Critical    - Keep track of this, as sandboxing is meant to be a way for an application to
        ///                 isolate xaml content from the hosting application.
        /// TreatAsSafe - the act of putting this content in a new webbrowser control (and by extention, a new PresentationHost)
        ///               isolates the xaml content from the rest of the application.
        ///</SecurityNote>
        [SecurityCritical, SecurityTreatAsSafe]
        internal static object XamlConverter(Stream stream, Uri baseUri, bool canUseTopLevelBrowser, bool sandboxExternalContent, bool allowAsync, bool isJournalNavigation, out XamlReader asyncObjectConverter)
        {
            asyncObjectConverter = null;

            if (sandboxExternalContent)
            {
                if (SecurityHelper.AreStringTypesEqual(baseUri.Scheme, BaseUriHelper.PackAppBaseUri.Scheme))
                {
                    baseUri = BaseUriHelper.ConvertPackUriToAbsoluteExternallyVisibleUri(baseUri);
                }

                stream.Close();

                WebBrowser webBrowser = new WebBrowser();
                webBrowser.Source = baseUri;
                return webBrowser;
            }
            else
            {
                ParserContext pc = new ParserContext();

                pc.BaseUri = baseUri;
                pc.SkipJournaledProperties = isJournalNavigation;

                if (allowAsync)
                {
                    XamlReader xr = new XamlReader();
                    asyncObjectConverter = xr;
                    xr.LoadCompleted += new AsyncCompletedEventHandler(OnParserComplete);
                    // XamlReader.Load will close the stream.
                    return xr.LoadAsync(stream, pc);
                }
                else
                {
                    // XamlReader.Load will close the stream.
                    return XamlReader.Load(stream, pc);
                }
            }
        }

	    private static void OnParserComplete(object sender, AsyncCompletedEventArgs args)
        {
            // We can get this event from cancellation. We do not care about the error if there is any
            // that happened as a result of cancellation.
            if ((! args.Cancelled) && (args.Error != null))
            {
                throw args.Error;
            }
        }

        internal static object HtmlXappConverter(Stream stream, Uri baseUri, bool canUseTopLevelBrowser, bool sandboxExternalContent, bool allowAsync, bool isJournalNavigation, out XamlReader asyncObjectConverter)
        {
            asyncObjectConverter = null;

            if (canUseTopLevelBrowser)
            {
                return null;
            }

            if (SecurityHelper.AreStringTypesEqual(baseUri.Scheme, BaseUriHelper.PackAppBaseUri.Scheme))
            {
                baseUri = BaseUriHelper.ConvertPackUriToAbsoluteExternallyVisibleUri(baseUri);
            }

            stream.Close();

            WebBrowser webBrowser = new WebBrowser();
            webBrowser.Source = baseUri;

            return webBrowser;
        }
    }
}


text:
// Copyright 2017, Jeffrey E. Bedard
#include "xcb.h"
// Include here to check syntax:
#include "JBDim.h"
#include <errno.h>
#include <string.h>
#include <sys/select.h>
#include <xcb/xcb_cursor.h>
#include "log.h"
#include "util.h"
bool jb_xcb_cookie_has_error(xcb_connection_t * x, const xcb_void_cookie_t c)
{
  xcb_generic_error_t * e = xcb_request_check(x, c);
  if (!e)
    return false;
  free(e);
  return true;
}
static _Noreturn void xerr(xcb_connection_t * x, const char * msg)
{
  xcb_disconnect(x);
  if (errno)
    perror(msg);
  else
    fprintf(stderr, "%s\n", msg);
  exit(1);
}
void jb_check_x(xcb_connection_t * x)
{
  switch(xcb_connection_has_error(x)) {
  case 0: // Success
    break;
  case XCB_CONN_ERROR:
    xerr(x, "X transport error, DISPLAY unavailable");
    break;
  case XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
    xerr(x, "Extension not supported");
    break;
  case XCB_CONN_CLOSED_MEM_INSUFFICIENT:
    xerr(x, "Insufficient memory");
    break;
  case XCB_CONN_CLOSED_REQ_LEN_EXCEED:
    xerr(x, "Request length exceeded");
    break;
  case XCB_CONN_CLOSED_PARSE_ERR:
    xerr(x, "Invalid DISPLAY string");
    break;
  case XCB_CONN_CLOSED_INVALID_SCREEN:
    xerr(x, "Invalid screen");
    break;
  }
}
xcb_connection_t * jb_get_xcb_connection(const char * display, int * screen)
{
  errno = 0;
  xcb_connection_t * x = xcb_connect(display, screen);
  jb_check_x(x);
  return x;
}
xcb_screen_t * jb_get_xcb_screen(xcb_connection_t * x)
{
  return xcb_setup_roots_iterator(xcb_get_setup(x)).data;
}
pixel_t jb_get_pixel(xcb_connection_t * x, const xcb_colormap_t cmap,
  const char * color)
{
  xcb_alloc_named_color_cookie_t c = xcb_alloc_named_color(x,
    cmap, strlen(color), color);
  xcb_alloc_named_color_reply_t * r
  = xcb_alloc_named_color_reply(x, c, NULL);
  if (jb_check(r, "Could not allocate color"))
    return 0;
  pixel_t p = r->pixel;
  free(r);
  return p;
}
pixel_t jb_get_rgb_pixel(xcb_connection_t * x, const xcb_colormap_t cm,
  const uint16_t r, const uint16_t g, const uint16_t b)
{
  xcb_alloc_color_cookie_t c = xcb_alloc_color(x, cm, r, g, b);
  xcb_alloc_color_reply_t * rpl = xcb_alloc_color_reply(x, c, NULL);
  if(jb_check(rpl, "Could not allocate RGB color"))
    return 0;
  const pixel_t p = rpl->pixel;
  free(rpl);
  return p;
}
pixel_t jb_set_fg(xcb_connection_t * x, const xcb_gcontext_t gc, const pixel_t p)
{
  xcb_change_gc(x, gc, XCB_GC_FOREGROUND, &(uint32_t){p});
  return p;
}
pixel_t jb_set_bg(xcb_connection_t * x, const xcb_gcontext_t gc, const pixel_t p)
{
  xcb_change_gc(x, gc, XCB_GC_BACKGROUND, &(uint32_t){p});
  return p;
}
static pixel_t jb_set_named_color(xcb_connection_t * xc, const xcb_gcontext_t gc,
  const char * color, const bool is_fg)
{
  return (is_fg ? jb_set_fg : jb_set_bg)(xc, gc,
    jb_get_pixel(xc, jb_get_default_colormap(xc), color));
}
pixel_t jb_set_named_fg(xcb_connection_t * xc, const xcb_gcontext_t gc,
  const char * color)
{
  return jb_set_named_color(xc, gc, color, true);
}
pixel_t jb_set_named_bg(xcb_connection_t * xc, const xcb_gcontext_t gc,
  const char * color)
{
  return jb_set_named_color(xc, gc, color, false);
}
xcb_atom_t jb_get_atom(xcb_connection_t * x, const char * name)
{
  xcb_intern_atom_reply_t * r = xcb_intern_atom_reply(x,
    xcb_intern_atom(x, false, strlen(name), name), NULL);
  const xcb_atom_t a = r->atom;
  free(r);
  return a;
}
static xcb_colormap_t get_cmap_from_winattr(xcb_connection_t * xc,
  xcb_get_window_attributes_cookie_t wac)
{
  xcb_get_window_attributes_reply_t * r
  = xcb_get_window_attributes_reply(xc, wac, NULL);
  jb_require(r, "Could not get colormap information.");
  const xcb_colormap_t cm = r->colormap;
  free(r);
  return cm;
}
xcb_colormap_t jb_get_colormap(xcb_connection_t * xc,
  const xcb_window_t win)
{
  return get_cmap_from_winattr(xc,
    xcb_get_window_attributes(xc, win));
}
xcb_colormap_t jb_get_default_colormap(xcb_connection_t * xc)
{
  return jb_get_xcb_screen(xc)->default_colormap;
}
/* Create a gc with foreground and background as specified.
   If gc is passed as 0, a new gc value is generated and returned.  */
xcb_gcontext_t jb_create_gc(xcb_connection_t * xc, xcb_gcontext_t gc,
  const xcb_window_t win, const char * restrict fg,
  const char * restrict bg)
{
  // defer processing reply
  const xcb_get_window_attributes_cookie_t wac
  = xcb_get_window_attributes(xc, win);
  if (!gc)
    gc = xcb_generate_id(xc);
  {
    xcb_void_cookie_t c
    = xcb_create_gc_checked(xc, gc, win, 0, NULL);
    xcb_generic_error_t * e = xcb_request_check (xc, c);
    if (jb_check(!e, "Could not create gc"))
      free(e);
  }
  const xcb_colormap_t cm = get_cmap_from_winattr(xc, wac);
  const pixel_t fgpx = jb_get_pixel(xc, cm, fg);
  const pixel_t bgpx = jb_get_pixel(xc, cm, bg);
  xcb_change_gc(xc, gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND,
    (uint32_t[]){fgpx, bgpx});
  return gc;
}
bool jb_next_event_timed(xcb_connection_t * x,
  xcb_generic_event_t ** e, const uint32_t delay)
{
#if 0
  jb_check_x(x);
  int fd = xcb_get_file_descriptor(x);
  fd_set r;
  FD_ZERO(&r);
  FD_SET(fd, &r);
  if (select(fd + 1, &r, NULL, NULL, &(struct timeval){
    .tv_usec = delay}))
    // event occurred before timeout:
    *e = xcb_poll_for_event(x);
  return *e != NULL;
#endif

//#if 0
  jb_check_x(x);
  if ((*e = xcb_poll_for_event(x)))
    return true;
  int fd = xcb_get_file_descriptor(x);
  fd_set r;
  FD_ZERO(&r);
  FD_SET(fd, &r);
  if (!select(fd + 1, &r, NULL, NULL, &(struct timeval){
    .tv_usec = delay}))
    return false; // timeout
  // event occurred before timeout:
  *e = xcb_poll_for_event(x);
  return true;
//#endif
}
/* Open font specified by name.  Initialized fid must be supplied.
 * If font cannot be opened, try 'fixed' before failing.  */
bool jb_open_font(xcb_connection_t * xc, xcb_font_t fid,
  const char * name)
{
  xcb_void_cookie_t c = xcb_open_font_checked(xc, fid,
    strlen(name), name);
  if (jb_xcb_cookie_has_error(xc, c)) {
    LIBJB_WARN("Failed to load font: %s", name);
    return false;
  }
  return true;
}
void jb_set_window_name(xcb_connection_t * xc, const xcb_window_t win,
  char * name)
{
  xcb_change_property(xc, XCB_PROP_MODE_REPLACE, win,
    XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
    strlen(name), name);
}
void jb_set_icon_name(xcb_connection_t * xc, const xcb_window_t win,
  char * name)
{
  xcb_change_property(xc, XCB_PROP_MODE_REPLACE, win,
    XCB_ATOM_WM_ICON_NAME, XCB_ATOM_STRING, 8,
    strlen(name), name);
}
xcb_cursor_t jb_get_cursor(xcb_connection_t * xc,
  const char * restrict name)
{
  xcb_cursor_context_t * ctx;
  xcb_cursor_context_new(xc, jb_get_xcb_screen(xc), &ctx);
  const xcb_cursor_t c = xcb_cursor_load_cursor(ctx, name);
  xcb_cursor_context_free(ctx);
  return c;
}


text:
//
//  WJTitleView.h
//  WithTheMind
//
//  Created by wangju on 16/4/22.
//  Copyright © 2016年 wangju. All rights reserved.
//

#import <UIKit/UIKit.h>

@class WJTitleView;
@class WJNavView;
@protocol WJTitleViewDelegate <NSObject>

@optional

- (void)titleView :(WJTitleView *)titleView didSelectButton:(UIButton *)button atNavView:(WJNavView *)navView;

@end

@interface WJTitleView : UIView

@property (nonatomic,copy) NSString *title;

@property (nonatomic,weak) id<WJTitleViewDelegate> delegate;

- (void)indicatorButtonClicked:(UIButton *)button;

/** 导航条左边的按钮 */
@property (nonatomic,weak) UIButton *leftButton;

/** 导航条右边的按钮 */
@property (nonatomic,weak) UIButton *rightButton;

/** 标签 */
@property (nonatomic,strong) NSArray *titleArr;

@property (nonatomic,weak) UIView *indicatorBar;

@property (nonatomic,weak) WJNavView *navView;

@property (nonatomic,strong) UIImageView *titleBGView;

- (void)setupTitleViewHidden:(BOOL)hidden;

@end


text:
package com.amazon.webservices.awsecommerceservice._2011_08_01;

import java.io.Serializable;
import com.leansoft.nano.annotation.*;
import java.util.List;

@RootElement(name = "CartGetResponse", namespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
public class CartGetResponse implements Serializable {

    private static final long serialVersionUID = -1L;

	@Element(name = "OperationRequest")
	@Order(value=0)
	public OperationRequest operationRequest;

	@Element(name = "Cart")
	@Order(value=1)
	public List<Cart> cart;

}


text:
var Canvas = require('canvas'),
    canvas = new Canvas(800, 800),
    ctx = canvas.getContext('2d'),
    Chart = require('../'),
    fs = require('fs'),
    data = JSON.parse(fs.readFileSync('./pie.json'));

Chart(ctx).Pie(data, {});

canvas.toBuffer(function (err, buf) {
  if (err) throw err;
  fs.writeFile(__dirname + '/pie.png', buf);
});


text:
$(document).ready(function(){
  console.log('hello')

var contactform =  document.getElementById('contactForm');
    contactform.setAttribute('action', '//formspree.io/' +
    'soundguytravis' + '@' + 'hotmail' + '.' + 'com');
});


text:
<?php
namespace frontend\models;

use Yii;
use yii\web\IdentityInterface;
use yii\web\User as WebUser;
use common\models\Board;

/**
 * This class extends the more generic User Identity Class from the common branch
 * It's main purpose is to provide functionality for managing the active board status
 * In the session and cookies.
 *
 * User model
 *
 * @property integer $id
 * @property string $username
 * @property string $password_hash
 * @property string $password_reset_token
 * @property string $email
 * @property string $auth_key
 * @property integer $status
 * @property integer $created_at
 * @property integer $updated_at
 * @property string $password write-only password
 * @property integer $board_id
 *
 */
class User extends \common\models\User implements IdentityInterface
{

	const ACTIVE_BOARD_COOKIE_NAME = 'activeBoard'; // Cookie Name for the active Board
	const ACTIVE_BOARD_SESSION_VARIABLE_NAME = 'activeBoard'; // Variable Name for the active Board used in the Session

	/**
	 *
	 */
	public function init()
	{
		parent::init();
		yii::$app->user->on(WebUser::EVENT_AFTER_LOGIN, [$this, 'afterLoginHandler']);
	}

	/**
	 * After a User is logged in, a Board for this user will be activated.
	 *
	 * A user can be a member of zero, one or more boards (when zero the user is automatically logged out).
	 *
	 * In normal operation the active board is stored in the session as well as the Active Board cookie.
	 * This function checks if this is the case and if not, attempts to set things up in this way.
	 *
	 * The result of this handler depends on the contents of the session and cookie values as well as
	 * the contents of the user's board_id attribute.
	 *
	 * If the session value is present it will be checked if it is valid and all values set appropriately
	 *
	 * If no session then the cookie value is checked for validity and all values are set appropriately
	 *
	 * If neither session nor cookie values exist then the value is determined from the user record
	 *
	 * The contents of the users board_id attribute are evaluated as follows:
	 * It can contain:
	 *  - no board ID
	 *  - one board ID
	 *  - many board IDs
	 *  - (in addition, board IDs can be valid or invalid, i.e. the corresponding Board exists)
	 *
	 * If no board Id, cookie and session are set to zero
	 * If one board ID, the values are automatically set to this ID
	 * Id many board IDs, the values for the session and cookie are set to the first valid Board ID,
	 *
	 * @param $event Yii\web\UserEvent
	 */
	public function afterLoginHandler($event)
	{
		$userBoardIds = explode(',', $event->identity->board_id);
		$sessionBoardId = $this->getSessionActiveBoardId();
		$cookieBoardId = $this->getCookieActiveBoardId();

		if ($sessionBoardId) {
			if ($this->boardExists($sessionBoardId) && in_array($sessionBoardId, $userBoardIds)) {
				$this->activateBoard($sessionBoardId);
			} else {
				$this->deactivateAllBoards();
			}
		} elseif ($cookieBoardId) {
			if ($this->boardExists($cookieBoardId) && in_array($cookieBoardId, $userBoardIds)) {
				$this->activateBoard($cookieBoardId);
			} else {
				$this->deactivateAllBoards();
			}
		} elseif (count($userBoardIds)) {
			// Find the first Board Id from the user which actually exists as a Board
			$boardFound = false;
			foreach($userBoardIds as $searchForBoardId) {
				if ($this->boardExists($searchForBoardId)) {
					$boardFound = $searchForBoardId;
					break;
				}
			}
			if ($boardFound) {
				$this->activateBoard($boardFound);
			} else {
				$this->deactivateAllBoards();
			}
		}
	}

	/**
	 * @return mixed
	 */
	public function getSessionActiveBoardId()
	{
		return Yii::$app->getSession()->get(self::ACTIVE_BOARD_SESSION_VARIABLE_NAME);
	}

	/**
	 * @param $value
	 * @return mixed
	 */
	public function setSessionActiveBoardId($value)
	{
		return Yii::$app->getSession()->set(self::ACTIVE_BOARD_SESSION_VARIABLE_NAME, $value);
	}

	/**
	 * @return string
	 */
	public function getCookieActiveBoardId()
	{
		return Yii::$app->request->getCookies()->getValue(self::ACTIVE_BOARD_COOKIE_NAME, 0);
	}

	/**
	 * @param $value
	 * @return mixed
	 */
	public function setCookieActiveBoardId($value)
	{
		$cookieCollection = Yii::$app->response->getCookies();

		return $cookieCollection->add(new \yii\web\Cookie([
            'name' => self::ACTIVE_BOARD_COOKIE_NAME,
            'value' => $value,
			'expire' => time() + 7 * 24 * 60 * 60
		]));
	}

	/**
	 * Returns the active board ID for this user. Session has precedence over the Cookie value
	 *
	 * @return mixed|string
	 */
	public function getUserActiveBoardId()
	{
		$sessionBoardId = $this->getSessionActiveBoardId();
		$cookieBoardId = $this->getCookieActiveBoardId();

		return $sessionBoardId ? $sessionBoardId : $cookieBoardId;
	}

	/**
	 * Sets the session and cookie values to be 0, i.e. inactive for this user
	 */
	public function deactivateAllBoards()
	{
		$this->setSessionActiveBoardId(0);
		$this->setCookieActiveBoardId(0);
	}

	/**
	 * Sets the session and cookie values to be $boardId
	 *
	 * @param $boardId
	 */
	public function activateBoard($boardId)
	{
		if ($this->boardExists($boardId)) {
			$this->setSessionActiveBoardId($boardId);
			$this->setCookieActiveBoardId($boardId);
            Board::setCurrentActiveBoard();
        } else {
			$this->deactivateAllBoards();
		}
	}

	/**
	 * @param $boardId
	 * @return null|static
	 */
	protected function boardExists($boardId)
	{
		return Board::findOne($boardId);
	}

	/**
	 * @inheritdoc
	 */
	public function attributeLabels()
	{
		return [
			'username' => \Yii::t('app', 'Username'),
			'password' => \Yii::t('app', 'Password'),
		];
	}

}


text:
require 'spec_helper'
require 'template_tree/node'
require 'template_tree/formatters/ascii'

RSpec.describe TemplateTree::Formatters::Ascii do
  let(:tree) do
    TemplateTree::Node.from_a(["a", [["b", [["c", []]]], ["d", []]]])
  end

  it "prints a natty tree" do
    expected = <<-EOS
a
├── b
|   └── c
└── d
EOS

    expect(subject.format(tree)).to eq expected.strip
  end
end


text:
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.io.FileOutputStream;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class CFCryptoWrapperTest
{
    private static final String testString = "wpWda/IF;Vj1<3s#.=?esoFU&?!}jH}\\t)ZQ{VD0z*f4huF=~\"F4:cS:+j+TW:z";
    private static CFCryptoWrapper cfCryptoWrapper;
    private static File encryptedKeyFile;
    private static File publicKeyFile;
    private static File privateKeyFile;
    private static String encryptedString;

    @BeforeClass
    public static void setUpClass() throws Exception
    {
        publicKeyFile = new File("test/publickey.der");
        privateKeyFile = new File("test/private.der");
        encryptedKeyFile = new File("test/encryptedKey");

        // generate the key pair
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        PrivateKey privateKey = keyGen.genKeyPair().getPrivate();
        PublicKey publicKey = keyGen.genKeyPair().getPublic();

        // write public key to file
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
        FileOutputStream fos = new FileOutputStream(publicKeyFile);
        fos.write(x509EncodedKeySpec.getEncoded());
        fos.close();

        // write private key to file
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
        fos = new FileOutputStream(privateKeyFile);
        fos.write(pkcs8EncodedKeySpec.getEncoded());
        fos.close();

        assertTrue(publicKeyFile.exists());
        assertTrue(privateKeyFile.exists());

        CFCrypto cfCrypto = new CFCrypto();
        cfCrypto.saveKey(encryptedKeyFile, publicKeyFile);
        cfCryptoWrapper = new CFCryptoWrapper(encryptedKeyFile.getPath(), privateKeyFile.getPath());
    }

    @AfterClass
    public static void tearDownClass() throws Exception
    {
        System.gc(); // quick and dirty workaround to get java to release the file lock
        Thread.sleep(10); // gc sometimes isn't quick enough

        assertTrue(publicKeyFile.delete());
        assertTrue(privateKeyFile.delete());
        assertTrue(encryptedKeyFile.delete());
    }

    @Test
    public void testEncrypt() throws Exception
    {
        encryptedString = cfCryptoWrapper.encrypt(testString);
    }

    @Test
    public void testDecrypt() throws Exception
    {
        String decryptedString = cfCryptoWrapper.decrypt(encryptedString);
        assertEquals(testString, decryptedString);
    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

	<TITLE>
	libsndfile
	</TITLE>
	<META NAME="Author"      CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
    <META NAME="Version"     CONTENT="libsndfile-1.0.28">
	<META NAME="Description" CONTENT="The libsndfile Home Page">
	<META NAME="Keywords"    CONTENT="WAV AIFF AU SVX PAF NIST W64 libsndfile sound audio dsp Linux">
	<META NAME="ROBOTS" 	 CONTENT="NOFOLLOW">
	<LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
	<LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">

		History -+-
		Features -+-
		Similar or Related Projects -+-
		News

		Development -+-
		Programming Interface -+-
		Bug Reporting -+-
		Download

		FAQ -+-
		Mailing Lists -+-
		Change Log -+-
		Licensing Information -+-
		See Also

	Libsndfile is a C library for reading and writing files containing sampled sound
	(such as MS Windows WAV and the Apple/SGI AIFF format) through one standard
	library interface. It is released in source code format under the
		Gnu Lesser General Public License.

	The library was written to compile and run on a Linux system but should compile
	and run on just about any Unix (including MacOS X).
	There are also pre-compiled binaries available for 32 and 64 bit windows.

	It was designed to handle both little-endian (such as WAV) and big-endian
	(such as AIFF) data, and to compile and run correctly on little-endian (such as Intel
	and DEC/Compaq Alpha) processor systems as well as big-endian processor systems such
	as Motorola 68k, Power PC, MIPS and Sparc.
	Hopefully the design of the library will also make it easy to extend for reading and
	writing new sound file formats.

    It has been compiled and tested (at one time or another) on the following systems:

Every platform supported by Debian GNU/Linux including x86_64-linux-gnu,
		i486-linux-gnu, powerpc-linux-gnu, sparc-linux-gnu, alpha-linux-gnu,
		mips-linux-gnu and armel-linux-gnu.

powerpc-apple-darwin7.0 (Mac OS X 10.3)

sparc-sun-solaris2.8 (using gcc)

mips-sgi-irix5.3 (using gcc)

QNX 6.0

i386-unknown-openbsd2.9

	At the moment, each new release is being tested on i386 Linux, x86_64 Linux,
	PowerPC Linux, Win32 and Win64.

Features

	libsndfile has the following main features :

 Ability to read and write a large number of file formats.

 A simple, elegant and easy to use Applications Programming Interface.

 Usable on Unix, Win32, MacOS and others.

 On the fly format conversion, including endian-ness swapping, type conversion
			and bitwidth scaling.

 Optional normalisation when reading floating point data from files containing
			integer data.

 Ability to open files in read/write mode.

 The ability to write the file header without closing the file (only on files
			open for write or read/write).

 Ability to query the library about all supported formats and retrieve text
			strings describing each format.

	libsndfile has a comprehensive test suite so that each release is as bug free
	as possible.
	When new bugs are found, new tests are added to the test suite to ensure that
	these bugs don't creep back into the code.
	When new features are added, tests are added to the test suite to make sure that
	these features continue to work correctly even when they are old features.

	The following table lists the file formats and encodings that libsndfile can read
	and write.
	The file formats are arranged across the top and encodings along the left
	edge.

	Micro- soft
WAV
	SGI / Apple
AIFF / AIFC
	Sun / DEC /
NeXT
AU / SND
	Header- less
RAW
	Paris Audio
File
PAF
	Commo- dore
Amiga
IFF / SVX
	Sphere
Nist
WAV
	IRCAM
SF
	Creative
VOC
	Sound forge
W64
	GNU Octave 2.0
MAT4
	GNU Octave 2.1
MAT5
	Portable Voice Format
PVF
	Fasttracker 2
XI
	HMM Tool Kit
HTK
	Apple
CAF
	Sound
Designer II
SD2
	Free Lossless Audio Codec
FLAC

Unsigned 8 bit PCM
	R/W	R/W	 	R/W
	 	 	 	 	R/W
	R/W	 	R/W

Signed 8 bit PCM
	 	R/W	R/W	R/W
	R/W	R/W	R/W
	 	 	 	 	R/W
	 	 	R/W	R/W	R/W

Signed 16 bit PCM
	R/W	R/W	R/W	R/W
	R/W	R/W	R/W	R/W
	R/W	R/W	R/W	R/W
	R/W	 	R/W	R/W
	R/W	R/W

Signed 24 bit PCM
	R/W	R/W	R/W	R/W
	R/W	 	R/W	R/W
	 	R/W
	 	 	R/W	R/W	R/W

Signed 32 bit PCM
	R/W	R/W	R/W	R/W
	 	 	R/W	R/W
	R/W	R/W	R/W	R/W
	 	 	R/W

32 bit float
	R/W	R/W	R/W	R/W
	 	 	 	R/W
	R/W	R/W	R/W
	 	 	R/W

64 bit double
	R/W	R/W	R/W
	R/W
	 	R/W	R/W	R/W
	 	 	 	R/W

u-law encoding
	R/W	R/W	R/W	R/W
	 	 	R/W	R/W	R/W
	R/W
	R/W

A-law encoding
	R/W	R/W	R/W	R/W
	 	 	R/W	R/W	R/W
	R/W
	R/W

IMA ADPCM
	R/W
	 	 	 	 	R/W

MS ADPCM
	R/W
	 	 	 	R/W

GSM 6.10
	R/W	R/W	 	R/W
	 	 	 	R/W

G721 ADPCM 32kbps
	R/W	 	R/W

G723 ADPCM 24kbps
	 	 	R/W

G723 ADPCM 40kbps
	 	 	R/W

12 bit DWVW
	 	R/W	 	R/W

16 bit DWVW
	 	R/W	 	R/W

24 bit DWVW
	 	R/W	 	R/W

Ok Dialogic ADPCM
	 	 	 	R/W

8 bit DPCM

	 	R/W

16 bit DPCM

	 	R/W

From version 1.0.18, libsndfile also reads and writes
	FLAC
and
	Ogg/Vorbis.

	Some of the file formats I am also interested in adding are:

 Kurzweil K2000 sampler files.

 Ogg Speex.

	I have decided that I will not be adding support for MPEG Layer 3 (commonly
	known as MP3) due to the patent issues surrounding this file format.
	See

		the FAQ
	for more.

	Other file formats may also be added on request.

History

	My first attempt at reading and writing WAV files was in 1990 or so under Windows
	3.1.
	I started using Linux in early 1995 and contributed some code to the
		wavplay
	program.
	That contributed code would eventually mutate into this library.
	As one of my interests is Digital Signal Processing (DSP) I decided that as well as
	reading data from an audio file in the native format (typically 16 bit short integers)
	it would also be useful to be able to have the library do the conversion to floating
	point numbers for DSP applications.
	It then dawned on me that whatever file format (anything from 8 bit unsigned chars,
	to 32 bit floating point numbers) the library should be able to convert the data to
	whatever format the library user wishes to use it in.
	For example, in a sound playback program, the library caller typically wants the sound
	data in 16 bit short integers to dump into a sound card even though the data in the
	file may be 32 bit floating point numbers (ie Microsoft's WAVE_FORMAT_IEEE_FLOAT
	format).
	Another example would be someone doing speech recognition research who has recorded
	some speech as a 16 bit WAV file but wants to process it as double precision floating
	point numbers.

    Here is the release history for libsndfile :

Version 0.0.8 (Feb 15 1999) First official release.

Version 0.0.28 (Apr 26 2002) Final release of version 0 of libsndfile.

Version 1.0.0rc1 (Jun 24 2002) Release candidate 1 of version 1 of libsndfile.

Version 1.0.0rc6 (Aug 14 2002) MacOS 9 fixes.

Version 1.0.0 (Aug 16 2002) First 1.0.X release.

Version 1.0.1 (Sep 14 2002) Added MAT4 and MAT5 file formats.

Version 1.0.2 (Nov 24 2002) Added VOX ADPCM format.

Version 1.0.3 (Dec 09 2002) Fixes for Linux on ia64 CPUs.

Version 1.0.4 (Feb 02 2003) New file formats and functionality.

Version 1.0.5 (May 03 2003) One new file format and new functionality.

Version 1.0.6 (Feb 08 2004) Large file fix for Linux/Solaris, new functionality
		and Win32 improvements.

Version 1.0.7 (Feb 24 2004) Fix build problems on MacOS X and fix ia64/MIPS etc
		clip mode detction.

Version 1.0.8 (Mar 14 2004) Minor bug fixes.

Version 1.0.9 (Mar 30 2004) Add AVR format. Improve handling of some WAV files.

Version 1.0.10 (Jun 15 2004) Minor bug fixes. Fix support for Win32 MinGW compiler.

Version 1.0.11 (Nov 15 2004) Add SD2 file support, reading of loop data in WAV and AIFF.
				Minor bug fixes.

Version 1.0.12 (Sep 30 2005) Add FLAC and CAF file support, virtual I/O interface.
				Minor bug fixes and cleanups.

Version 1.0.13 (Jan 21 2006) Add read/write of instrument chunks. Minor bug fixes.

Version 1.0.14 (Feb 19 2006) Minor bug fixes. Start shipping windows binary/source ZIP.

Version 1.0.15 (Mar 16 2006) Minor bug fixes.

Version 1.0.16 (Apr 30 2006) Add support for RIFX. Other minor feature enhancements and
				bug fixes.

Version 1.0.17 (Aug 31 2006) Add C++ wrapper sndfile.hh. Minor bug fixes and cleanups.

Version 1.0.18 (Feb 07 2009) Add Ogg/Vorbis suppport, remove captive libraries, many
				new features and bug fixes. Generate Win32 and Win64 pre-compiled binaries.

Version 1.0.19 (Mar 02 2009) Fix for CVE-2009-0186. Huge number of minor fixes as a
				result of static analysis.

Version 1.0.20 (May 14 2009) Fix for potential heap overflow.

Version 1.0.21 (December 13 2009) Bunch of minor bug fixes.

Version 1.0.22 (October 04 2010) Bunch of minor bug fixes.

Version 1.0.23 (October 10 2010) Minor bug fixes.

Version 1.0.24 (March 23 2011) Minor bug fixes.

Version 1.0.25 (July 13 2011) Fix for Secunia Advisory SA45125. Minor bug fixes and
				improvements.

Version 1.0.26 (November 22 2015) Fix for CVE-2014-9496, CVE-2014-9756 and CVE-2015-7805.
				Add ALAC/CAF support. Minor bug fixes and improvements.

Version 1.0.27 (June 19 2016) Fix a seek regression in 1.0.26. Add metadata read/write
				for CAF and RF64. FIx PAF endian-ness issue.

Version 1.0.28 (April 2 2017) Fix buffer overruns in FLAC and ID3 handling code. Reduce default
				header memory requirements. Fix detection of Large File Support for 32 bit systems.

Similar or Related Projects

SoX is a program for
		converting between sound file formats.

Wavplay started out
		as a minimal WAV file player under Linux and has mutated into Gnuwave, a client/server
		application for more general multimedia and games sound playback.

Audiofile (libaudiofile) is
		a library similar to libsndfile but with a different programming interface. The
		author Michael Pruett has set out to clone (and fix some bugs in) the libaudiofile
		library which ships with SGI's IRIX OS.

sndlib.tar.gz is
		another library written by Bill Schottstaedt of CCRMA.

Licensing

	libsndfile is released under the terms of the GNU Lesser General Public License,
	of which there are two versions;
		version 2.1
	and
		version 3.
	To maximise the compatibility of libsndfile, the user may choose to use libsndfile
	under either of the above two licenses.
	You can also read a simple explanation of the ideas behind the GPL and the LGPL
		here.

	You can use libsndfile with
		Free Software,
		Open Source,
	proprietary, shareware or other closed source applications as long as libsndfile
	is used as a dynamically loaded library and you abide by a small number of other
	conditions (read the LGPL for more info).
	With applications released under the GNU GPL you can also use libsndfile statically
	linked to your application.

	I would like to see libsndfile used as widely as possible but I would prefer it
	if you released software that uses libsndfile as
		Free Software
	or
		Open Source.
	However, if you put in a great deal of effort building a significant application
	which simply uses libsndfile for file I/O, then I have no problem with you releasing
	that as closed source and charging as much money as you want for it as long as you
	abide by the license.

Download

	Here is the latest version. It is available in the following formats:

Source code as a .tar.gz :
			libsndfile-1.0.28.tar.gz
			and
			GPG signature.

Win32 installer:

			libsndfile-1.0.28-w32-setup.exe (thoroughly tested under
			Wine)
			and
			GPG signature.

Win64 installer:

			libsndfile-1.0.28-w64-setup.exe (thoroughly tested under
			Wine)
			and
			GPG signature.

    The GPG signature can be validated at
		Keybase.IO.

The Win32 installer should work on Windows Vista or later.

	Pre-release versions of libsndfile are available
			here
	and are announced on the
			libsndfile-devel
	mailing list.

See Also

		sndfile-tools
		: a small collection of programs which use libsndfile.

	The latest version of this document can be found
		here.

Author :

		Erik de Castro Lopo

This page has been accessed

times.


text:
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

using AllReady.Areas.Admin.ViewModels.VolunteerTask;
using AllReady.Features.Events;
using AllReady.Models;

using MediatR;

namespace AllReady.Areas.Admin.ViewModels.Validators.VolunteerTask
{
    public class VolunteerTaskEditViewModelValidator : IValidateVolunteerTaskEditViewModelValidator
    {
        private readonly IMediator _mediator;

        // list of executable extensions (same extensions as blocked by Gmail)
        private readonly HashSet<string> ForbiddenExtensions = new HashSet<string> { ".ade", ".adp", ".bat", ".chm", ".cmd", ".com", ".cpl", ".exe", ".hta", ".ins", ".isp", ".jar", ".jse", ".lib", ".lnk", ".mde", ".msc", ".msp", ".mst", ".pif", ".scr", ".sct", ".shb", ".sys", ".vb", ".vbe", ".vbs", ".vxd", ".wsc", ".wsf", ".wsh" };

        public VolunteerTaskEditViewModelValidator(IMediator mediator)
        {
            this._mediator = mediator;
        }

        public async Task<List<KeyValuePair<string, string>>> Validate(EditViewModel viewModel)
        {
            var result = new List<KeyValuePair<string, string>>();

            var parentEvent = await this._mediator.SendAsync(new EventByEventIdQuery { EventId = viewModel.EventId });

            // Rule - End date cannot be earlier than start date
            if (viewModel.EndDateTime < viewModel.StartDateTime)
            {
                result.Add(new KeyValuePair<string, string>(nameof(viewModel.EndDateTime), "End date cannot be earlier than the start date"));
            }

            // Rule - Start date cannot be out of range of parent event
            if (viewModel.StartDateTime < parentEvent.StartDateTime)
            {
                result.Add(new KeyValuePair<string, string>(nameof(viewModel.StartDateTime), $"Start date cannot be earlier than the event start date {parentEvent.StartDateTime:g}."));
            }

            // Rule - End date cannot be out of range of parent event
            if (viewModel.EndDateTime > parentEvent.EndDateTime)
            {
                result.Add(new KeyValuePair<string, string>(nameof(viewModel.EndDateTime), $"The end date of this task cannot be after the end date of the event {parentEvent.EndDateTime:g}"));
            }

            // Rule - Attachments are optional
            if (!string.IsNullOrEmpty(viewModel.NewAttachment?.FileName))
            {
                // Rule - New attachment must have content
                if (viewModel.NewAttachment == null || viewModel.NewAttachment.Length == 0)
                {
                    result.Add(new KeyValuePair<string, string>(nameof(viewModel.NewAttachment), "The attachment is empty"));
                }

                // Rule - Attachment must not be executable
                string ext = Path.GetExtension(viewModel.NewAttachment.FileName).ToLower();
                if (this.ForbiddenExtensions.Contains(ext))
                {
                    result.Add(new KeyValuePair<string, string>(nameof(viewModel.NewAttachment), "The attachment has an invalid extension. The disallowed file types are :" + string.Join(", ", this.ForbiddenExtensions)));
                }
            }

            // Rule - Itinerary volunteerTasks must start and end on same calendar day
            if (parentEvent.EventType == EventType.Itinerary)
            {
                if (viewModel.StartDateTime.Date != viewModel.EndDateTime.Date)
                {
                    result.Add(new KeyValuePair<string, string>(nameof(viewModel.EndDateTime), "For itinerary events the task end date must occur on the same day as the start date. Tasks cannot span multiple days"));
                }
            }

            return result;
        }
    }
}


text:
<?php

/**
 * This code was generated by
 * \ / _    _  _|   _  _
 * | (_)\/(_)(_|\/| |(/_  v1.0.0
 * /       /
 */

namespace Twilio\Tests\Integration\Taskrouter\V1\Workspace;

use Twilio\Exceptions\DeserializeException;
use Twilio\Exceptions\TwilioException;
use Twilio\Http\Response;
use Twilio\Tests\HolodeckTestCase;
use Twilio\Tests\Request;

class TaskTest extends HolodeckTestCase {
    public function testFetchRequest(): void {
        $this->holodeck->mock(new Response(500, ''));

        try {
            $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                         ->tasks("WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")->fetch();
        } catch (DeserializeException $e) {}
          catch (TwilioException $e) {}

        $this->assertRequest(new Request(
            'get',
            'https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Tasks/WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
        ));
    }

    public function testFetchResponse(): void {
        $this->holodeck->mock(new Response(
            200,
            '
            {
                "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "age": 25200,
                "assignment_status": "pending",
                "attributes": "{\\"body\\": \\"hello\\"}",
                "date_created": "2014-05-14T18:50:02Z",
                "date_updated": "2014-05-15T07:26:06Z",
                "task_queue_entered_date": "2014-05-14T18:50:02Z",
                "priority": 0,
                "reason": "Test Reason",
                "sid": "WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_queue_sid": "WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_channel_sid": "TCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_channel_unique_name": "task-channel",
                "timeout": 60,
                "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workflow_sid": "WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workspace_sid": "WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workflow_friendly_name": "Test Workflow",
                "task_queue_friendly_name": "Test Queue",
                "addons": "{}",
                "links": {
                    "task_queue": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/TaskQueues/WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "workflow": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Workflows/WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "workspace": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "reservations": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Reservations"
                }
            }
            '
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks("WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")->fetch();

        $this->assertNotNull($actual);
    }

    public function testUpdateRequest(): void {
        $this->holodeck->mock(new Response(500, ''));

        $options = ['ifMatch' => "if_match", ];

        try {
            $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                         ->tasks("WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")->update($options);
        } catch (DeserializeException $e) {}
          catch (TwilioException $e) {}

        $headers = ['If-Match' => "if_match", ];

        $this->assertRequest(new Request(
            'post',
            'https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Tasks/WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
            [],
            [],
            $headers
        ));
    }

    public function testUpdateResponse(): void {
        $this->holodeck->mock(new Response(
            200,
            '
            {
                "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "age": 25200,
                "assignment_status": "pending",
                "attributes": "{\\"body\\": \\"hello\\"}",
                "date_created": "2014-05-14T18:50:02Z",
                "date_updated": "2014-05-15T07:26:06Z",
                "task_queue_entered_date": "2014-05-14T18:50:02Z",
                "priority": 0,
                "reason": "Test Reason",
                "sid": "WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_queue_sid": "WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_channel_sid": "TCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_channel_unique_name": "task-channel",
                "timeout": 60,
                "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workflow_sid": "WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workspace_sid": "WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workflow_friendly_name": "Test Workflow",
                "task_queue_friendly_name": "Test Queue",
                "addons": "{}",
                "links": {
                    "task_queue": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/TaskQueues/WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "workflow": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Workflows/WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "workspace": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "reservations": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Reservations"
                }
            }
            '
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks("WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")->update();

        $this->assertNotNull($actual);
    }

    public function testDeleteRequest(): void {
        $this->holodeck->mock(new Response(500, ''));

        $options = ['ifMatch' => "if_match", ];

        try {
            $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                         ->tasks("WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")->delete($options);
        } catch (DeserializeException $e) {}
          catch (TwilioException $e) {}

        $headers = ['If-Match' => "if_match", ];

        $this->assertRequest(new Request(
            'delete',
            'https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Tasks/WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
            [],
            [],
            $headers
        ));
    }

    public function testDeleteResponse(): void {
        $this->holodeck->mock(new Response(
            204,
            null
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks("WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")->delete();

        $this->assertTrue($actual);
    }

    public function testReadRequest(): void {
        $this->holodeck->mock(new Response(500, ''));

        try {
            $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                         ->tasks->read();
        } catch (DeserializeException $e) {}
          catch (TwilioException $e) {}

        $this->assertRequest(new Request(
            'get',
            'https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Tasks'
        ));
    }

    public function testReadFullResponse(): void {
        $this->holodeck->mock(new Response(
            200,
            '
            {
                "meta": {
                    "first_page_url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks?TaskQueueSid=WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&Priority=1&TaskQueueName=task_queue_name&WorkflowName=workflow_name&WorkflowSid=WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&AssignmentStatus=pending%2Creserved&PageSize=50&Page=0",
                    "key": "tasks",
                    "next_page_url": null,
                    "page": 0,
                    "page_size": 50,
                    "previous_page_url": null,
                    "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks?TaskQueueSid=WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&Priority=1&TaskQueueName=task_queue_name&WorkflowName=workflow_name&WorkflowSid=WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&AssignmentStatus=pending%2Creserved&PageSize=50&Page=0"
                },
                "tasks": [
                    {
                        "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "age": 25200,
                        "assignment_status": "pending",
                        "attributes": "{\\"body\\": \\"hello\\"}",
                        "date_created": "2014-05-14T14:26:54Z",
                        "date_updated": "2014-05-15T16:03:42Z",
                        "task_queue_entered_date": "2014-05-14T14:26:54Z",
                        "priority": 0,
                        "reason": "Test Reason",
                        "sid": "WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "task_queue_sid": "WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "task_channel_sid": "TCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "task_channel_unique_name": "task-channel",
                        "timeout": 60,
                        "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "workflow_sid": "WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "workspace_sid": "WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                        "workflow_friendly_name": "Test Workflow",
                        "task_queue_friendly_name": "Test Queue",
                        "addons": "{}",
                        "links": {
                            "task_queue": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/TaskQueues/WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                            "workflow": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Workflows/WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                            "workspace": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                            "reservations": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Reservations"
                        }
                    }
                ]
            }
            '
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks->read();

        $this->assertGreaterThan(0, \count($actual));
    }

    public function testReadEmptyResponse(): void {
        $this->holodeck->mock(new Response(
            200,
            '
            {
                "meta": {
                    "first_page_url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks?TaskQueueSid=WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&Priority=1&TaskQueueName=task_queue_name&WorkflowName=workflow_name&WorkflowSid=WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&AssignmentStatus=pending&PageSize=50&Page=0",
                    "key": "tasks",
                    "next_page_url": null,
                    "page": 0,
                    "page_size": 50,
                    "previous_page_url": null,
                    "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks?TaskQueueSid=WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&Priority=1&TaskQueueName=task_queue_name&WorkflowName=workflow_name&WorkflowSid=WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&AssignmentStatus=pending&PageSize=50&Page=0"
                },
                "tasks": []
            }
            '
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks->read();

        $this->assertNotNull($actual);
    }

    public function testReadAssignmentStatusMultipleResponse(): void {
        $this->holodeck->mock(new Response(
            200,
            '
            {
                "meta": {
                    "first_page_url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks?TaskQueueSid=WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&Priority=1&TaskQueueName=task_queue_name&WorkflowName=workflow_name&WorkflowSid=WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&AssignmentStatus=pending&PageSize=50&Page=0",
                    "key": "tasks",
                    "next_page_url": null,
                    "page": 0,
                    "page_size": 50,
                    "previous_page_url": null,
                    "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks?TaskQueueSid=WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&Priority=1&TaskQueueName=task_queue_name&WorkflowName=workflow_name&WorkflowSid=WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&AssignmentStatus=pending&PageSize=50&Page=0"
                },
                "tasks": []
            }
            '
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks->read();

        $this->assertNotNull($actual);
    }

    public function testCreateRequest(): void {
        $this->holodeck->mock(new Response(500, ''));

        try {
            $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                         ->tasks->create();
        } catch (DeserializeException $e) {}
          catch (TwilioException $e) {}

        $this->assertRequest(new Request(
            'post',
            'https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Tasks'
        ));
    }

    public function testCreateResponse(): void {
        $this->holodeck->mock(new Response(
            201,
            '
            {
                "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "age": 25200,
                "assignment_status": "pending",
                "attributes": "{\\"body\\": \\"attributes\\"}",
                "date_created": "2014-05-14T18:50:02Z",
                "date_updated": "2014-05-15T07:26:06Z",
                "task_queue_entered_date": null,
                "priority": 1,
                "reason": "Test Reason",
                "sid": "WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_queue_sid": "WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_channel_sid": "TCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "task_channel_unique_name": "unique",
                "timeout": 60,
                "url": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workspace_sid": "WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workflow_sid": "WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                "workflow_friendly_name": "Example Workflow",
                "task_queue_friendly_name": "Example Task Queue",
                "addons": "{}",
                "links": {
                    "task_queue": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/TaskQueues/WQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "workflow": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Workflows/WWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "workspace": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "reservations": "https://taskrouter.twilio.com/v1/Workspaces/WSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Tasks/WTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Reservations"
                }
            }
            '
        ));

        $actual = $this->twilio->taskrouter->v1->workspaces("WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                                               ->tasks->create();

        $this->assertNotNull($actual);
    }
}


text:
To get help if you're having trouble, you can use one of the following resources:

- [The Racket Reference](http://docs.racket-lang.org/reference/index.html)
- [/r/racket](https://www.reddit.com/r/racket) is the Racket subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/racket) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.