Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add instructions for windows and fix failing unit tests #632

Merged
merged 12 commits into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Experiment with flagd in your browser using [the Killercoda tutorial](https://ki
```

Or use docker:
_Note - In Windows, use WSL system for both the file location and Docker runtime. Mixed file systems does not
work and this is a [limitation of Docker](https://github.com/docker/for-win/issues/8479)_

```sh
docker run \
Expand All @@ -73,7 +75,7 @@ Experiment with flagd in your browser using [the Killercoda tutorial](https://ki
--uri file:./example_flags.flagd.json
```

Or use docker:
Or use docker ( _Note - In Windows, this requires WSL system for both the file location and Docker runtime_):

```sh
docker run \
Expand All @@ -98,6 +100,14 @@ Experiment with flagd in your browser using [the Killercoda tutorial](https://ki
-d '{"flagKey":"myStringFlag","context":{}}' -H "Content-Type: application/json"
```

For Windows we recommend using a [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) terminal.
Otherwise, use the following with `cmd`:

```sh
set json={"flagKey":"myStringFlag","context":{}}
curl -i -X POST -H "Content-Type: application/json" -d %json:"=\"% "localhost:8013/schema.v1.Service/ResolveString"
```

Result:

```json
Expand Down
145 changes: 66 additions & 79 deletions core/pkg/sync/file/filepath_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"reflect"
msync "sync"
"testing"
Expand All @@ -16,120 +17,112 @@ import (
)

const (
fetchDirName = "test"
fetchFileName = "to_fetch.json"
fetchFileContents = "fetch me"
)

func TestSimpleReSync(t *testing.T) {
tests := map[string]struct {
fileContents string
expectedDataSync sync.DataSync
}{
"simple-read": {
fileContents: "hello",
expectedDataSync: sync.DataSync{
FlagData: "hello",
Source: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Type: sync.ALL,
},
},
fetchDirName := t.TempDir()
source := filepath.Join(fetchDirName, fetchFileName)
expectedDataSync := sync.DataSync{
FlagData: "hello",
Source: source,
Type: sync.ALL,
}

handler := Sync{
URI: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
URI: source,
Logger: logger.NewLogger(nil, false),
}

for test, tt := range tests {
t.Run(test, func(t *testing.T) {
defer t.Cleanup(cleanupFilePath)
setupDir(t)
createFile(t)
writeToFile(t, tt.fileContents)

ctx := context.Background()
dataSyncChan := make(chan sync.DataSync, 1)
createFile(t, fetchDirName)
writeToFile(t, fetchDirName, "hello")
ctx := context.Background()
dataSyncChan := make(chan sync.DataSync, 1)

go func() {
err := handler.ReSync(ctx, dataSyncChan)
if err != nil {
log.Fatalf("Error start sync: %s", err.Error())
return
}
}()
go func() {
err := handler.ReSync(ctx, dataSyncChan)
if err != nil {
log.Fatalf("Error start sync: %s", err.Error())
return
}
}()

select {
case s := <-dataSyncChan:
if !reflect.DeepEqual(tt.expectedDataSync, s) {
t.Errorf("resync failed, incorrect datasync value, got %v want %v", s, tt.expectedDataSync)
}
case <-time.After(5 * time.Second):
t.Error("timed out waiting for datasync")
}
})
select {
case s := <-dataSyncChan:
if !reflect.DeepEqual(expectedDataSync, s) {
t.Errorf("resync failed, incorrect datasync value, got %v want %v", s, expectedDataSync)
}
case <-time.After(5 * time.Second):
t.Error("timed out waiting for datasync")
}
}

func TestSimpleSync(t *testing.T) {
readDirName := t.TempDir()
updateDirName := t.TempDir()
deleteDirName := t.TempDir()
tests := map[string]struct {
manipulationFuncs []func(t *testing.T)
expectedDataSync []sync.DataSync
fetchDirName string
}{
"simple-read": {
fetchDirName: readDirName,
manipulationFuncs: []func(t *testing.T){
func(t *testing.T) {
writeToFile(t, fetchFileContents)
writeToFile(t, readDirName, fetchFileContents)
},
},
expectedDataSync: []sync.DataSync{
{
FlagData: fetchFileContents,
Source: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Source: fmt.Sprintf("%s/%s", readDirName, fetchFileName),
Type: sync.ALL,
},
},
},
"update-event": {
fetchDirName: updateDirName,
manipulationFuncs: []func(t *testing.T){
func(t *testing.T) {
writeToFile(t, fetchFileContents)
writeToFile(t, updateDirName, fetchFileContents)
},
func(t *testing.T) {
writeToFile(t, "new content")
writeToFile(t, updateDirName, "new content")
},
},
expectedDataSync: []sync.DataSync{
{
FlagData: fetchFileContents,
Source: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Source: fmt.Sprintf("%s/%s", updateDirName, fetchFileName),
Type: sync.ALL,
},
{
FlagData: "new content",
Source: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Source: fmt.Sprintf("%s/%s", updateDirName, fetchFileName),
Type: sync.ALL,
},
},
},
"delete-event": {
fetchDirName: deleteDirName,
manipulationFuncs: []func(t *testing.T){
func(t *testing.T) {
writeToFile(t, fetchFileContents)
writeToFile(t, deleteDirName, fetchFileContents)
},
func(t *testing.T) {
deleteFile(t, fetchDirName, fetchFileName)
deleteFile(t, deleteDirName, fetchFileName)
},
},
expectedDataSync: []sync.DataSync{
{
FlagData: fetchFileContents,
Source: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Source: fmt.Sprintf("%s/%s", deleteDirName, fetchFileName),
Type: sync.ALL,
},
{
FlagData: defaultState,
Source: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Source: fmt.Sprintf("%s/%s", deleteDirName, fetchFileName),
Type: sync.DELETE,
},
},
Expand All @@ -138,16 +131,14 @@ func TestSimpleSync(t *testing.T) {

for test, tt := range tests {
t.Run(test, func(t *testing.T) {
defer t.Cleanup(cleanupFilePath)
setupDir(t)
createFile(t)
createFile(t, tt.fetchDirName)

ctx := context.Background()

dataSyncChan := make(chan sync.DataSync, len(tt.expectedDataSync))

syncHandler := Sync{
URI: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
URI: fmt.Sprintf("%s/%s", tt.fetchDirName, fetchFileName),
Logger: logger.NewLogger(nil, false),
Mux: &msync.RWMutex{},
}
Expand Down Expand Up @@ -199,13 +190,17 @@ func TestSimpleSync(t *testing.T) {
}

func TestFilePathSync_Fetch(t *testing.T) {
successDirName := t.TempDir()
falureDirName := t.TempDir()
tests := map[string]struct {
fpSync Sync
handleResponse func(t *testing.T, fetched string, err error)
fetchDirName string
}{
"success": {
fetchDirName: successDirName,
fpSync: Sync{
URI: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
URI: fmt.Sprintf("%s/%s", successDirName, fetchFileName),
Logger: logger.NewLogger(nil, false),
},
handleResponse: func(t *testing.T, fetched string, err error) {
Expand All @@ -219,8 +214,9 @@ func TestFilePathSync_Fetch(t *testing.T) {
},
},
"not found": {
fetchDirName: falureDirName,
fpSync: Sync{
URI: fmt.Sprintf("%s/%s", fetchDirName, "not_found"),
URI: fmt.Sprintf("%s/%s", falureDirName, "not_found"),
Logger: logger.NewLogger(nil, false),
},
handleResponse: func(t *testing.T, fetched string, err error) {
Expand All @@ -233,10 +229,8 @@ func TestFilePathSync_Fetch(t *testing.T) {

for name, tt := range tests {
t.Run(name, func(t *testing.T) {
setupDir(t)
createFile(t)
writeToFile(t, fetchFileContents)
defer t.Cleanup(cleanupFilePath)
createFile(t, tt.fetchDirName)
writeToFile(t, tt.fetchDirName, fetchFileContents)

data, err := tt.fpSync.fetch(context.Background())

Expand All @@ -246,16 +240,15 @@ func TestFilePathSync_Fetch(t *testing.T) {
}

func TestIsReadySyncFlag(t *testing.T) {
fetchDirName := t.TempDir()
fpSync := Sync{
URI: fmt.Sprintf("%s/%s", fetchDirName, fetchFileName),
Logger: logger.NewLogger(nil, false),
Mux: &msync.RWMutex{},
}

setupDir(t)
createFile(t)
writeToFile(t, fetchFileContents)
defer t.Cleanup(cleanupFilePath)
createFile(t, fetchDirName)
writeToFile(t, fetchDirName, fetchFileContents)
if fpSync.IsReady() != false {
t.Errorf("expected not to be ready")
}
Expand Down Expand Up @@ -283,31 +276,25 @@ func TestIsReadySyncFlag(t *testing.T) {
}
}

func cleanupFilePath() {
if err := os.RemoveAll(fetchDirName); err != nil {
log.Fatalf("rmdir: %v", err)
}
}

func deleteFile(t *testing.T, dirName string, fileName string) {
if err := os.Remove(fmt.Sprintf("%s/%s", dirName, fileName)); err != nil {
t.Fatal(err)
}
}

func setupDir(t *testing.T) {
if err := os.Mkdir(fetchDirName, os.ModePerm); err != nil {
t.Fatal(err)
}
}

func createFile(t *testing.T) {
if _, err := os.Create(fmt.Sprintf("%s/%s", fetchDirName, fetchFileName)); err != nil {
func createFile(t *testing.T, fetchDirName string) {
f, err := os.Create(fmt.Sprintf("%s/%s", fetchDirName, fetchFileName))
defer func(file *os.File) {
if err := file.Close(); err != nil {
log.Fatalf("close file: %v", err)
}
}(f)
if err != nil {
t.Fatal(err)
}
}

func writeToFile(t *testing.T, fileContents string) {
func writeToFile(t *testing.T, fetchDirName, fileContents string) {
file, err := os.OpenFile(fmt.Sprintf("%s/%s", fetchDirName, fetchFileName), os.O_RDWR, 0o644)
if err != nil {
t.Fatal(err)
Expand Down
Loading