Removing usage of SPN in pipelines (#1431)

* Removing usage of SPN in pipelines
This commit is contained in:
Vikas Bhansali 2024-06-17 16:19:22 +05:30 коммит произвёл GitHub
Родитель 0790773436
Коммит cefb0226f9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
24 изменённых файлов: 504 добавлений и 1999 удалений

9
.github/workflows/codeql-analysis.yml поставляемый
Просмотреть файл

@ -35,13 +35,14 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
@ -50,7 +51,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -64,4 +65,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3

Просмотреть файл

@ -46,7 +46,7 @@ steps:
# azcli login
- script: |
az login --service-principal -u $(AZTEST_CLIENT) -p $(AZTEST_SECRET) --tenant $(AZTEST_TENANT)
az login --identity --username $(ACLI_BLOBFUSE_MSI_APP_ID)
displayName: 'Azure CLI login'
- task: Go@0
@ -74,9 +74,6 @@ steps:
echo "\"msi-appid\"": "\"$(AZTEST_APP_ID)\"", >> $cnfFile
echo "\"msi-resid\"": "\"$(AZTEST_RES_ID)\"", >> $cnfFile
echo "\"msi-objid\"": "\"$(AZTEST_OBJ_ID)\"", >> $cnfFile
echo "\"spn-client\"": "\"$(AZTEST_CLIENT)\"", >> $cnfFile
echo "\"spn-tenant\"": "\"$(AZTEST_TENANT)\"", >> $cnfFile
echo "\"spn-secret\"": "\"$(AZTEST_SECRET)\"", >> $cnfFile
echo "\"skip-msi\"": "${{ parameters.skip_msi }}", >> $cnfFile
echo "\"skip-azcli\"": "false", >> $cnfFile
echo "\"proxy-address\"": "\"${{ parameters.proxy_address }}\"" >> $cnfFile

Просмотреть файл

@ -80,9 +80,6 @@ steps:
echo "\"msi-appid\"": "\"$(AZTEST_APP_ID)\"", >> $cnfFile
echo "\"msi-resid\"": "\"$(AZTEST_RES_ID)\"", >> $cnfFile
echo "\"msi-objid\"": "\"$(AZTEST_OBJ_ID)\"", >> $cnfFile
echo "\"spn-client\"": "\"$(AZTEST_CLIENT)\"", >> $cnfFile
echo "\"spn-tenant\"": "\"$(AZTEST_TENANT)\"", >> $cnfFile
echo "\"spn-secret\"": "\"$(AZTEST_SECRET)\"", >> $cnfFile
echo "\"skip-msi\"": "true", >> $cnfFile
echo "\"skip-azcli\"": "true", >> $cnfFile
echo "\"proxy-address\"": "\"\"" >> $cnfFile

Просмотреть файл

@ -124,9 +124,6 @@ steps:
echo "\"msi-appid\"": "\"$(AZTEST_APP_ID)\"", >> $cnfFile
echo "\"msi-resid\"": "\"$(AZTEST_RES_ID)\"", >> $cnfFile
echo "\"msi-objid\"": "\"$(AZTEST_OBJ_ID)\"", >> $cnfFile
echo "\"spn-client\"": "\"$(AZTEST_CLIENT)\"", >> $cnfFile
echo "\"spn-tenant\"": "\"$(AZTEST_TENANT)\"", >> $cnfFile
echo "\"spn-secret\"": "\"$(AZTEST_SECRET)\"", >> $cnfFile
echo "\"skip-msi\"": "${{ parameters.skip_msi }}", >> $cnfFile
echo "\"skip-azcli\"": "${{ parameters.skip_azcli }}", >> $cnfFile
echo "\"proxy-address\"": "\"${{ parameters.proxy_address }}\"" >> $cnfFile
@ -146,7 +143,7 @@ steps:
# azcli login
- script: |
az login --service-principal -u $(AZTEST_CLIENT) -p $(AZTEST_SECRET) --tenant $(AZTEST_TENANT)
az login --identity --username $(ACLI_BLOBFUSE_MSI_APP_ID)
displayName: 'Azure CLI login'
condition: eq('${{ parameters.skip_azcli }}', 'false')

Просмотреть файл

@ -42,8 +42,6 @@ parameters:
default: false
steps:
- checkout: none
# Get the host details on which these test are running
- script: |
echo $(Description)
@ -52,6 +50,9 @@ steps:
# Create directory structure and prepare to mount
- ${{ parameters.installStep }}
- checkout: none
- script: |
sudo rm -rf $(ROOT_DIR)
sudo mkdir -p $(ROOT_DIR)
@ -101,7 +102,6 @@ steps:
quick_test: ${{ parameters.quick_test }}
verbose_log: ${{ parameters.verbose_log }}
clone: ${{ parameters.clone }}
stream_direct_test: false
# TODO: These can be removed one day and replace all instances of ${{ parameters.temp_dir }} with $(TEMP_DIR) since it is a global variable
temp_dir: $(TEMP_DIR)
mount_dir: $(MOUNT_DIR)
@ -122,7 +122,6 @@ steps:
quick_test: ${{ parameters.quick_test }}
verbose_log: ${{ parameters.verbose_log }}
clone: ${{ parameters.clone }}
stream_direct_test: false
# TODO: These can be removed one day and replace all instances of ${{ parameters.temp_dir }} with $(TEMP_DIR) since it is a global variable
temp_dir: $(TEMP_DIR)
mount_dir: $(MOUNT_DIR)

Просмотреть файл

@ -31,9 +31,6 @@ parameters:
- name: clone
type: boolean
default: false
- name: stream_direct_test
type: boolean
default: false
steps:
- script: |

Просмотреть файл

@ -31,9 +31,6 @@ parameters:
- name: clone
type: boolean
default: false
- name: stream_direct_test
type: boolean
default: false
- name: enable_symlink_adls
type: boolean
default: false
@ -67,7 +64,6 @@ steps:
artifact_name: '${{ parameters.distro_name }}_${{ parameters.idstring }}.txt'
verbose_log: ${{ parameters.verbose_log }}
clone: ${{ parameters.clone }}
stream_direct_test: ${{ parameters.stream_direct_test }}
enable_symlink_adls: ${{ parameters.enable_symlink_adls }}
mountStep:
script: |

Просмотреть файл

@ -19,9 +19,6 @@ parameters:
- name: quick_test
type: boolean
default: true
- name: stream_direct_test
type: boolean
default: false
- name: enable_symlink_adls
type: boolean
default: false
@ -69,7 +66,7 @@ steps:
- task: Go@0
inputs:
command: 'test'
arguments: '-v -timeout=2h ./... -args -mnt-path=${{ parameters.mount_dir }} -adls=${{parameters.adls}} -clone=${{parameters.clone}} -tmp-path=${{parameters.temp_dir}} -quick-test=${{parameters.quick_test}} -stream-direct-test=${{parameters.stream_direct_test}} -enable-symlink-adls=${{parameters.enable_symlink_adls}} -distro-name="${{parameters.distro_name}}"'
arguments: '-v -timeout=2h ./... -args -mnt-path=${{ parameters.mount_dir }} -adls=${{parameters.adls}} -clone=${{parameters.clone}} -tmp-path=${{parameters.temp_dir}} -quick-test=${{parameters.quick_test}} -enable-symlink-adls=${{parameters.enable_symlink_adls}} -distro-name="${{parameters.distro_name}}"'
workingDirectory: ${{ parameters.working_dir }}/test/e2e_tests
displayName: 'E2E Test: ${{ parameters.idstring }}'
timeoutInMinutes: 120

Просмотреть файл

@ -6,6 +6,8 @@ parameters:
default: "null"
steps:
# Create directory structure and prepare to mount
- ${{ parameters.installStep }}
- checkout: none
# Get the host details on which these test are running
@ -14,8 +16,6 @@ steps:
hostnamectl
displayName: 'Print Agent Info'
# Create directory structure and prepare to mount
- ${{ parameters.installStep }}
- script: |
sudo rm -rf $(ROOT_DIR)
sudo mkdir -p $(ROOT_DIR)

Просмотреть файл

@ -5,14 +5,10 @@ parameters:
type: string
- name: account_endpoint
type: string
- name: spn_account_endpoint
type: string
- name: adls
type: boolean
- name: account_name
type: string
- name: spn_account_name
type: string
- name: account_key
type: string
- name: account_sas
@ -43,23 +39,13 @@ parameters:
type: boolean
- name: test_sas_credential
type: boolean
- name: test_spn_credential
type: boolean
- name: test_azcli_credential
type: boolean
- name: test_stream
type: boolean
- name: stream_config
type: string
- name: stream_filename_config
type: string
- name: test_azurite
type: boolean
default: false
- name: sas_credential_config
type: string
- name: spn_credential_config
type: string
- name: azcli_credential_config
type: string
- name: azurite_config
@ -96,42 +82,6 @@ steps:
displayName: Print config file
condition: ${{ parameters.test_key_credential }}
# Stream e2e
- script: |
cd ${{ parameters.working_dir }}
${{ parameters.working_dir }}/blobfuse2 gen-test-config --config-file=azure_stream.yaml --container-name=${{ parameters.container }} --output-file=${{ parameters.stream_config }}
displayName: Create Stream Config File
env:
ACCOUNT_TYPE: ${{ parameters.account_type }}
NIGHTLY_STO_ACC_NAME: ${{ parameters.account_name }}
NIGHTLY_STO_ACC_KEY: ${{ parameters.account_key }}
ACCOUNT_ENDPOINT: ${{ parameters.account_endpoint }}
VERBOSE_LOG: ${{ parameters.verbose_log }}
condition: ${{ parameters.test_stream }}
continueOnError: false
- script: cat ${{ parameters.stream_config }}
displayName: Print Stream config file with Handle Level Caching
condition: ${{ parameters.test_stream }}
# Stream e2e filename level caching
- script: |
cd ${{ parameters.working_dir }}
${{ parameters.working_dir }}/blobfuse2 gen-test-config --config-file=azure_stream_filename.yaml --container-name=${{ parameters.container }} --output-file=${{ parameters.stream_filename_config }}
displayName: Create Stream Config File
env:
ACCOUNT_TYPE: ${{ parameters.account_type }}
NIGHTLY_STO_ACC_NAME: ${{ parameters.account_name }}
NIGHTLY_STO_ACC_KEY: ${{ parameters.account_key }}
ACCOUNT_ENDPOINT: ${{ parameters.account_endpoint }}
VERBOSE_LOG: ${{ parameters.verbose_log }}
condition: ${{ parameters.test_stream }}
continueOnError: false
- script: cat ${{ parameters.stream_filename_config }}
displayName: Print Stream config file with Filename Caching
condition: ${{ parameters.test_stream }}
# Create sas credential config file if we need to test it
- script: |
cd ${{ parameters.working_dir }}
@ -150,33 +100,13 @@ steps:
displayName: Print SAS config file
condition: ${{ parameters.test_sas_credential }}
# Create spn credential config file if we need to test it
- script: |
cd ${{ parameters.working_dir }}
${{ parameters.working_dir }}/blobfuse2 gen-test-config --config-file=azure_spn.yaml --container-name=${{ parameters.container }} --temp-path=${{ parameters.temp_dir }} --output-file=${{ parameters.spn_credential_config }}
displayName: Create SPN Config File
env:
NIGHTLY_SPN_ACC_NAME: ${{ parameters.spn_account_name }}
NIGHTLY_SPN_CLIENT_ID: ${{ parameters.client_id }}
NIGHTLY_SPN_TENANT_ID: ${{ parameters.tenant_id }}
NIGHTLY_SPN_CLIENT_SECRET: ${{ parameters.client_secret }}
ACCOUNT_TYPE: ${{ parameters.account_type }}
ACCOUNT_ENDPOINT: ${{ parameters.spn_account_endpoint }}
VERBOSE_LOG: ${{ parameters.verbose_log }}
condition: ${{ parameters.test_spn_credential }}
continueOnError: false
- script: cat ${{ parameters.spn_credential_config }}
displayName: Print SPN config file
condition: ${{ parameters.test_spn_credential }}
# Create azcli credential config file if we need to test it
- script: |
cd ${{ parameters.working_dir }}
${{ parameters.working_dir }}/blobfuse2 gen-test-config --config-file=azure_cli.yaml --container-name=${{ parameters.container }} --temp-path=${{ parameters.temp_dir }} --output-file=${{ parameters.azcli_credential_config }}
displayName: Create Azure CLI Config File
env:
NIGHTLY_STO_BLOB_ACC_NAME: ${{ parameters.spn_account_name }}
NIGHTLY_STO_BLOB_ACC_NAME: ${{ parameters.account_name }}
ACCOUNT_TYPE: ${{ parameters.account_type }}
ACCOUNT_ENDPOINT: ${{ parameters.account_endpoint }}
VERBOSE_LOG: ${{ parameters.verbose_log }}
@ -246,47 +176,6 @@ steps:
quick_test: ${{ parameters.quick_test }}
verbose_log: ${{ parameters.verbose_log }}
clone: false
stream_direct_test: false
- ${{ if eq(parameters.test_stream, true) }}:
- template: e2e-tests.yml
parameters:
working_dir: ${{ parameters.working_dir }}
temp_dir: ${{ parameters.temp_dir }}
mount_dir: ${{ parameters.mount_dir }}
adls: ${{ parameters.adls }}
idstring: ${{ parameters.service }} with Streaming
distro_name: ${{ parameters.distro_name }}
quick_test: ${{ parameters.quick_test }}
artifact_name: '${{ parameters.distro_name }}_${{ parameters.service }}_stream.txt'
verbose_log: ${{ parameters.verbose_log }}
mountStep:
script: >
${{ parameters.working_dir }}/blobfuse2 mount ${{ parameters.mount_dir }} --config-file=${{ parameters.stream_config }}
--default-working-dir=${{ parameters.working_dir }}
displayName: 'E2E Test: Mount with Stream Configuration'
timeoutInMinutes: 3
continueOnError: false
- ${{ if eq(parameters.test_stream, true) }}:
- template: e2e-tests.yml
parameters:
working_dir: ${{ parameters.working_dir }}
temp_dir: ${{ parameters.temp_dir }}
mount_dir: ${{ parameters.mount_dir }}
adls: ${{ parameters.adls }}
idstring: ${{ parameters.service }} with Streaming with filename
distro_name: ${{ parameters.distro_name }}
quick_test: ${{ parameters.quick_test }}
artifact_name: '${{ parameters.distro_name }}_${{ parameters.service }}_stream_with_filename.txt'
verbose_log: ${{ parameters.verbose_log }}
mountStep:
script: >
${{ parameters.working_dir }}/blobfuse2 mount ${{ parameters.mount_dir }} --config-file=${{ parameters.stream_filename_config }}
--default-working-dir=${{ parameters.working_dir }}
displayName: 'E2E Test: Mount with Filename Stream Configuration'
timeoutInMinutes: 3
continueOnError: false
- ${{ if eq(parameters.test_sas_credential, true) }}:
- template: e2e-tests.yml
@ -307,25 +196,6 @@ steps:
timeoutInMinutes: 3
continueOnError: false
- ${{ if eq(parameters.test_spn_credential, true) }}:
- template: e2e-tests.yml
parameters:
working_dir: ${{ parameters.working_dir }}
mount_dir: ${{ parameters.mount_dir }}
temp_dir: ${{ parameters.temp_dir }}
adls: ${{ parameters.adls }}
idstring: ${{ parameters.service }} with SPN Credentials
distro_name: ${{ parameters.distro_name }}
artifact_name: '${{ parameters.distro_name }}_${{ parameters.service }}_spn.txt'
verbose_log: ${{ parameters.verbose_log }}
mountStep:
script: >
${{ parameters.working_dir }}/blobfuse2 mount ${{ parameters.mount_dir }} --config-file=${{ parameters.spn_credential_config }}
--default-working-dir=${{ parameters.working_dir }}
displayName: 'E2E Test: Mount with SPN Credential Configuration'
timeoutInMinutes: 3
continueOnError: false
- ${{ if eq(parameters.test_azcli_credential, true) }}:
- template: e2e-tests.yml
parameters:
@ -347,8 +217,8 @@ steps:
- ${{ if eq(parameters.test_azurite, true) }}:
- bash: |
sudo apt-get install azure-cli -y
sudo npm install -g azurite
sudo apt-get install azure-cli npm -y
sudo npm install -g azurite@3.29.0
sudo mkdir azurite
sudo azurite --silent --location azurite --debug azurite\debug.log &
az storage container create -n ${{ parameters.container }} --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;"
@ -375,22 +245,6 @@ steps:
#--------------------------------------- Tests: End to end tests with different File Cache configurations ------------------------------------------
- template: e2e-tests-spcl.yml
parameters:
conf_template: azure_key_lfu.yaml
config_file: ${{ parameters.config }}
container: ${{ parameters.container }}
temp_dir: ${{ parameters.temp_dir }}
mount_dir: ${{ parameters.mount_dir }}
adls: ${{ parameters.adls }}
account_name: ${{ parameters.account_name }}
account_key: ${{ parameters.account_key }}
account_type: ${{ parameters.account_type }}
account_endpoint: ${{ parameters.account_endpoint }}
idstring: "${{ parameters.service }} LFU policy"
distro_name: ${{ parameters.distro_name }}
verbose_log: ${{ parameters.verbose_log }}
- template: e2e-tests-spcl.yml
parameters:
conf_template: azure_key_lru_purge.yaml

Просмотреть файл

@ -13,23 +13,26 @@ jobs:
strategy:
matrix:
Ubuntu-20:
imageName: 'ubuntu-20.04'
AgentName: 'blobfuse-ubuntu20'
containerName: 'test-cnt-ubn-20'
fuselib: 'libfuse-dev'
tags: 'fuse2'
adlsSas: $(AZTEST_ADLS_CONT_SAS_UBN_20)
Ubuntu-22:
imageName: 'ubuntu-22.04'
AgentName: 'blobfuse-ubuntu22'
containerName: 'test-cnt-ubn-22'
fuselib: 'libfuse3-dev'
tags: 'fuse3'
adlsSas: $(AZTEST_ADLS_CONT_SAS_UBN_22)
pool:
vmImage: $(imageName)
name: "blobfuse-ubuntu-pool"
demands:
- ImageOverride -equals $(AgentName)
variables:
- group: NightlyBlobFuse
steps:
# ----------------------------------------------------------------
- template: 'azure-pipeline-templates/blobfuse2-ci-template.yml'
@ -44,7 +47,7 @@ jobs:
strategy:
matrix:
Ubuntu-22-ARM64:
imageName: 'blobfuse-ubn22-arm64'
AgentName: 'blobfuse-ubn22-arm64'
containerName: 'test-cnt-ubn-22'
fuselib: 'libfuse3-dev'
tags: 'fuse3'
@ -53,7 +56,7 @@ jobs:
pool:
name: "blobfuse-ubn-arm64-pool"
demands:
- ImageOverride -equals $(imageName)
- ImageOverride -equals $(AgentName)
variables:
- group: NightlyBlobFuse

Просмотреть файл

@ -28,14 +28,12 @@ stages:
matrix:
Ubuntu-20:
AgentName: 'blobfuse-ubuntu20'
imageName: 'ubuntu-20.04'
containerName: 'test-cnt-ubn-20'
fuselib: 'libfuse-dev'
fuselib2: 'fuse'
tags: 'fuse2'
Ubuntu-22:
AgentName: 'blobfuse-ubuntu22'
imageName: 'ubuntu-22.04'
containerName: 'test-cnt-ubn-22'
fuselib: 'libfuse3-dev'
fuselib2: 'fuse3'
@ -54,8 +52,6 @@ stages:
value: '$(Pipeline.Workspace)/blobfuse2_tmp'
- name: BLOBFUSE2_CFG
value: '$(Pipeline.Workspace)/blobfuse2.yaml'
- name: BLOBFUSE2_STREAM_CFG
value: '$(Pipeline.Workspace)/blobfuse2_stream.yaml'
- name: BLOBFUSE2_ADLS_CFG
value: '$(Pipeline.Workspace)/blobfuse2.adls.yaml'
- name: GOPATH
@ -236,84 +232,6 @@ stages:
workingDirectory: $(WORK_DIR)
displayName: "ADLS Coverage with profilers"
# -------------------------------------------------------
# Config Generation (Block Blob - LFU policy)
- script: |
cd $(WORK_DIR)
./blobfuse2.test -test.v -test.coverprofile=$(WORK_DIR)/blobfuse2_gentest2.cov gen-test-config --config-file=azure_key_lfu.yaml --container-name=$(containerName) --temp-path=$(TEMP_DIR) --output-file=$(BLOBFUSE2_CFG)
env:
NIGHTLY_STO_ACC_NAME: $(NIGHTLY_STO_BLOB_ACC_NAME)
NIGHTLY_STO_ACC_KEY: $(NIGHTLY_STO_BLOB_ACC_KEY)
ACCOUNT_TYPE: 'block'
ACCOUNT_ENDPOINT: 'https://$(NIGHTLY_STO_BLOB_ACC_NAME).blob.core.windows.net'
VERBOSE_LOG: false
displayName: 'Create Config File - LFU'
continueOnError: false
workingDirectory: $(WORK_DIR)
# Code Coverage with e2e-tests for block blob with lfu policy
- script: |
rm -rf $(MOUNT_DIR)/*
rm -rf $(TEMP_DIR)/*
./blobfuse2.test -test.v -test.coverprofile=$(WORK_DIR)/blobfuse2_block_lfu.cov mount $(MOUNT_DIR) --config-file=$(BLOBFUSE2_CFG) --foreground=true &
sleep 10
ps -aux | grep blobfuse2
rm -rf $(MOUNT_DIR)/*
cd test/e2e_tests
go test -v -timeout=7200s ./... -args -mnt-path=$(MOUNT_DIR) -tmp-path=$(TEMP_DIR)
cd -
./blobfuse2 unmount $(MOUNT_DIR)
sleep 5
workingDirectory: $(WORK_DIR)
displayName: "Block Blob LFU Coverage"
# -------------------------------------------------------
# Config Generation (Block Blob - Stream)
- script: |
cd $(WORK_DIR)
./blobfuse2.test -test.v -test.coverprofile=$(WORK_DIR)/blobfuse2_gentest3.cov gen-test-config --config-file=azure_stream.yaml --container-name=$(containerName) --temp-path=$(TEMP_DIR) --output-file=$(BLOBFUSE2_STREAM_CFG)
displayName: 'Create Config File - Stream'
env:
NIGHTLY_STO_ACC_NAME: $(NIGHTLY_STO_BLOB_ACC_NAME)
NIGHTLY_STO_ACC_KEY: $(NIGHTLY_STO_BLOB_ACC_KEY)
ACCOUNT_TYPE: 'block'
ACCOUNT_ENDPOINT: 'https://$(NIGHTLY_STO_BLOB_ACC_NAME).blob.core.windows.net'
VERBOSE_LOG: false
continueOnError: false
workingDirectory: $(WORK_DIR)
# Streaming test preparation
- script: |
rm -rf $(MOUNT_DIR)/*
rm -rf $(TEMP_DIR)/*
./blobfuse2.test -test.v -test.coverprofile=$(WORK_DIR)/blobfuse2_stream_prep.cov mount $(MOUNT_DIR) --config-file=$(BLOBFUSE2_CFG) --foreground=true &
sleep 10
ps -aux | grep blobfuse2
for i in {10,50,100,200,500,1024}; do echo $i; done | parallel --will-cite -j 5 'head -c {}M < /dev/urandom > $(WORK_DIR)/myfile_{}'
for i in {10,50,100,200,500,1024}; do echo $i; done | parallel --will-cite -j 5 'cp $(WORK_DIR)/myfile_{} $(MOUNT_DIR)/'
./blobfuse2 unmount "$(MOUNT_DIR)*"
sudo fusermount -u $(MOUNT_DIR)
sleep 5
workingDirectory: $(WORK_DIR)
displayName: "Block Blob Stream Preparation"
# Code Coverage with e2e-tests for block blob with streaming on
- script: |
rm -rf $(MOUNT_DIR)/*
rm -rf $(TEMP_DIR)/*
./blobfuse2.test -test.v -test.coverprofile=$(WORK_DIR)/blobfuse2_stream.cov mount $(MOUNT_DIR) --config-file=$(BLOBFUSE2_STREAM_CFG) --foreground=true &
sleep 10
ps -aux | grep blobfuse2
./blobfuse2 mount list
for i in {10,50,100,200,500,1024}; do echo $i; done | parallel --will-cite -j 5 'diff $(WORK_DIR)/myfile_{} $(MOUNT_DIR)/myfile_{}'
sudo fusermount -u $(MOUNT_DIR)
sleep 5
workingDirectory: $(WORK_DIR)
displayName: "Block Blob Stream Coverage"
# -------------------------------------------------------
# Config Generation (Block Blob) for cli options
- script: |
@ -596,7 +514,7 @@ stages:
sudo apt-get install python3-setuptools -y
sudo apt install python3-pip -y
sudo pip3 install mitmproxy
mitmdump -w proxy_logs.txt &
mitmdump -q -w proxy_logs.txt &
displayName: 'Install & Start Proxy'
# Configure Proxy cert & env
@ -674,7 +592,7 @@ stages:
- script: |
echo 'mode: count' > ./blobfuse2_coverage_raw.rpt
tail -q -n +2 ./*.cov >> ./blobfuse2_coverage_raw.rpt
cat ./blobfuse2_coverage_raw.rpt | grep -v mock_component | grep -v base_component | grep -v loopback | grep -v tools | grep -v "common/log" | grep -v "common/exectime" | grep -v "internal/stats_manager" | grep -v "main.go" | grep -v "component/azstorage/azauthmsi.go" | grep -v "component/azstorage/azauthcli.go" > ./blobfuse2_coverage.rpt
cat ./blobfuse2_coverage_raw.rpt | grep -v mock_component | grep -v base_component | grep -v loopback | grep -v tools | grep -v "common/log" | grep -v "common/exectime" | grep -v "common/types.go" | grep -v "internal/stats_manager" | grep -v "main.go" | grep -v "component/azstorage/azauthmsi.go" | grep -v "component/azstorage/azauthspn.go" | grep -v "component/stream" | grep -v "component/azstorage/azauthcli.go" > ./blobfuse2_coverage.rpt
go tool cover -func blobfuse2_coverage.rpt > ./blobfuse2_func_cover.rpt
go tool cover -html=./blobfuse2_coverage.rpt -o ./blobfuse2_coverage.html
go tool cover -html=./blobfuse2_ut.cov -o ./blobfuse2_ut.html
@ -717,7 +635,6 @@ stages:
matrix:
Ubuntu-20:
AgentName: 'blobfuse-ubuntu20'
imageName: 'ubuntu-20.04'
containerName: 'test-cnt-ubn-20'
fuselib: 'libfuse3-dev'
fuselib2: 'fuse3'
@ -736,8 +653,6 @@ stages:
value: '$(Pipeline.Workspace)/blobfuse2_tmp'
- name: BLOBFUSE2_CFG
value: '$(Pipeline.Workspace)/blobfuse2.yaml'
- name: BLOBFUSE2_STREAM_CFG
value: '$(Pipeline.Workspace)/blobfuse2_stream.yaml'
- name: BLOBFUSE2_ADLS_CFG
value: '$(Pipeline.Workspace)/blobfuse2.adls.yaml'
- name: GOPATH

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -687,115 +687,6 @@ func (suite *authTestSuite) TestAdlskMsiResId() {
}
}
func (suite *authTestSuite) TestBlockInvalidSpn() {
defer suite.cleanupTest()
stgConfig := AzStorageConfig{
container: storageTestConfigurationParameters.BlockContainer,
authConfig: azAuthConfig{
AuthMode: EAuthType.SPN(),
AccountType: EAccountType.BLOCK(),
AccountName: storageTestConfigurationParameters.BlockAccount,
ClientID: storageTestConfigurationParameters.SpnClientId,
TenantID: storageTestConfigurationParameters.SpnTenantId,
ClientSecret: "",
Endpoint: generateEndpoint(false, storageTestConfigurationParameters.BlockAccount, EAccountType.BLOCK()),
},
}
assert := assert.New(suite.T())
stg := NewAzStorageConnection(stgConfig)
if stg == nil {
assert.Fail("TestBlockInvalidSpn : Failed to create Storage object")
}
if err := stg.SetupPipeline(); err == nil {
assert.Fail("TestBlockInvalidSpn : Setup pipeline even though spn is invalid")
}
}
func (suite *authTestSuite) TestBlockInvalidTokenPathSpn() {
defer suite.cleanupTest()
_ = os.WriteFile("newtoken.txt", []byte("abcdef"), 0777)
defer os.Remove("newtoken.txt")
stgConfig := AzStorageConfig{
container: storageTestConfigurationParameters.BlockContainer,
authConfig: azAuthConfig{
AuthMode: EAuthType.SPN(),
AccountType: EAccountType.BLOCK(),
AccountName: storageTestConfigurationParameters.BlockAccount,
ClientID: storageTestConfigurationParameters.SpnClientId,
TenantID: storageTestConfigurationParameters.SpnTenantId,
ClientSecret: "",
Endpoint: generateEndpoint(false, storageTestConfigurationParameters.BlockAccount, EAccountType.BLOCK()),
OAuthTokenFilePath: "newtoken.txt",
},
}
assert := assert.New(suite.T())
stg := NewAzStorageConnection(stgConfig)
if stg == nil {
assert.Fail("TestBlockInvalidSpn : Failed to create Storage object")
}
_ = stg.SetupPipeline()
}
func (suite *authTestSuite) TestBlockSpn() {
defer suite.cleanupTest()
stgConfig := AzStorageConfig{
container: storageTestConfigurationParameters.BlockContainer,
authConfig: azAuthConfig{
AuthMode: EAuthType.SPN(),
AccountType: EAccountType.BLOCK(),
AccountName: storageTestConfigurationParameters.BlockAccount,
ClientID: storageTestConfigurationParameters.SpnClientId,
TenantID: storageTestConfigurationParameters.SpnTenantId,
ClientSecret: storageTestConfigurationParameters.SpnClientSecret,
Endpoint: generateEndpoint(false, storageTestConfigurationParameters.BlockAccount, EAccountType.BLOCK()),
},
}
suite.validateStorageTest("TestBlockSpn", stgConfig)
}
func (suite *authTestSuite) TestAdlsInvalidSpn() {
defer suite.cleanupTest()
stgConfig := AzStorageConfig{
container: storageTestConfigurationParameters.AdlsContainer,
authConfig: azAuthConfig{
AuthMode: EAuthType.SPN(),
AccountType: EAccountType.ADLS(),
AccountName: storageTestConfigurationParameters.AdlsAccount,
ClientID: storageTestConfigurationParameters.SpnClientId,
TenantID: storageTestConfigurationParameters.SpnTenantId,
ClientSecret: "",
Endpoint: generateEndpoint(false, storageTestConfigurationParameters.AdlsAccount, EAccountType.ADLS()),
},
}
assert := assert.New(suite.T())
stg := NewAzStorageConnection(stgConfig)
if stg == nil {
assert.Fail("TestAdlsInvalidSpn : Failed to create Storage object")
}
if err := stg.SetupPipeline(); err == nil {
assert.Fail("TestAdlsInvalidSpn : Setup pipeline even though spn is invalid")
}
}
func (suite *authTestSuite) TestAdlsSpn() {
defer suite.cleanupTest()
stgConfig := AzStorageConfig{
container: storageTestConfigurationParameters.AdlsContainer,
authConfig: azAuthConfig{
AuthMode: EAuthType.SPN(),
AccountType: EAccountType.ADLS(),
AccountName: storageTestConfigurationParameters.AdlsAccount,
ClientID: storageTestConfigurationParameters.SpnClientId,
TenantID: storageTestConfigurationParameters.SpnTenantId,
ClientSecret: storageTestConfigurationParameters.SpnClientSecret,
Endpoint: generateEndpoint(false, storageTestConfigurationParameters.AdlsAccount, EAccountType.ADLS()),
},
}
suite.validateStorageTest("TestAdlsSpn", stgConfig)
}
func (suite *authTestSuite) TestBlockAzCLI() {
defer suite.cleanupTest()
stgConfig := AzStorageConfig{

Просмотреть файл

@ -294,16 +294,7 @@ func (c *FileCache) Configure(_ bool) error {
}
cacheConfig := c.GetPolicyConfig(conf)
switch strings.ToLower(conf.Policy) {
case "lru":
c.policy = NewLRUPolicy(cacheConfig)
case "lfu":
c.policy = NewLFUPolicy(cacheConfig)
default:
log.Info("FileCache::Configure : Using default eviction policy")
c.policy = NewLRUPolicy(cacheConfig)
}
c.policy = NewLRUPolicy(cacheConfig)
if c.policy == nil {
log.Err("FileCache::Configure : failed to create cache eviction policy")

Просмотреть файл

@ -161,7 +161,7 @@ func (suite *fileCacheTestSuite) TestEmpty() {
func (suite *fileCacheTestSuite) TestConfig() {
defer suite.cleanupTest()
suite.cleanupTest() // teardown the default file cache generated
policy := "lfu"
policy := "lru"
maxSizeMb := 1024
cacheTimeout := 60
maxDeletion := 10
@ -178,10 +178,10 @@ func (suite *fileCacheTestSuite) TestConfig() {
suite.assert.Equal(suite.fileCache.tmpPath, suite.cache_path)
suite.assert.Equal(suite.fileCache.policy.Name(), policy)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).lowThreshold, lowThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).lowThreshold, lowThreshold)
suite.assert.Equal(suite.fileCache.createEmptyFile, createEmptyFile)
suite.assert.Equal(suite.fileCache.allowNonEmpty, allowNonEmptyTemp)
@ -192,7 +192,7 @@ func (suite *fileCacheTestSuite) TestConfig() {
func (suite *fileCacheTestSuite) TestConfigPolicyTimeout() {
defer suite.cleanupTest()
suite.cleanupTest() // teardown the default file cache generated
policy := "lfu"
policy := "lru"
maxSizeMb := 1024
cacheTimeout := 60
maxDeletion := 10
@ -209,11 +209,11 @@ func (suite *fileCacheTestSuite) TestConfigPolicyTimeout() {
suite.assert.Equal(suite.fileCache.tmpPath, suite.cache_path)
suite.assert.Equal(suite.fileCache.policy.Name(), policy)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).lowThreshold, lowThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).cacheTimeout, cacheTimeout)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).lowThreshold, lowThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).cacheTimeout, cacheTimeout)
suite.assert.Equal(suite.fileCache.createEmptyFile, createEmptyFile)
suite.assert.Equal(suite.fileCache.allowNonEmpty, allowNonEmptyTemp)
@ -224,7 +224,7 @@ func (suite *fileCacheTestSuite) TestConfigPolicyTimeout() {
func (suite *fileCacheTestSuite) TestConfigPolicyDefaultTimeout() {
defer suite.cleanupTest()
suite.cleanupTest() // teardown the default file cache generated
policy := "lfu"
policy := "lru"
maxSizeMb := 1024
cacheTimeout := defaultFileCacheTimeout
maxDeletion := 10
@ -241,11 +241,11 @@ func (suite *fileCacheTestSuite) TestConfigPolicyDefaultTimeout() {
suite.assert.Equal(suite.fileCache.tmpPath, suite.cache_path)
suite.assert.Equal(suite.fileCache.policy.Name(), policy)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).lowThreshold, lowThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).cacheTimeout, cacheTimeout)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).lowThreshold, lowThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).cacheTimeout, cacheTimeout)
suite.assert.Equal(suite.fileCache.createEmptyFile, createEmptyFile)
suite.assert.Equal(suite.fileCache.allowNonEmpty, allowNonEmptyTemp)
@ -256,7 +256,7 @@ func (suite *fileCacheTestSuite) TestConfigPolicyDefaultTimeout() {
func (suite *fileCacheTestSuite) TestConfigZero() {
defer suite.cleanupTest()
suite.cleanupTest() // teardown the default file cache generated
policy := "lfu"
policy := "lru"
maxSizeMb := 1024
cacheTimeout := 0
maxDeletion := 10
@ -273,10 +273,10 @@ func (suite *fileCacheTestSuite) TestConfigZero() {
suite.assert.Equal(suite.fileCache.tmpPath, suite.cache_path)
suite.assert.Equal(suite.fileCache.policy.Name(), policy)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lfuPolicy).lowThreshold, lowThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxSizeMB, maxSizeMb)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).maxEviction, maxDeletion)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).highThreshold, highThreshold)
suite.assert.EqualValues(suite.fileCache.policy.(*lruPolicy).lowThreshold, lowThreshold)
suite.assert.Equal(suite.fileCache.createEmptyFile, createEmptyFile)
suite.assert.Equal(suite.fileCache.allowNonEmpty, allowNonEmptyTemp)

Просмотреть файл

@ -1,483 +0,0 @@
/*
_____ _____ _____ ____ ______ _____ ------
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| --- | | | | |-----| |---- | | |-----| |----- ------
| | | | | | | | | | | | |
| ____| |_____ | ____| | ____| | |_____| _____| |_____ |_____
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
Copyright © 2020-2024 Microsoft Corporation. All rights reserved.
Author : <blobfusedev@microsoft.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
*/
package file_cache
import (
"os"
"strings"
"sync"
"time"
"github.com/Azure/azure-storage-fuse/v2/common/log"
)
type lfuPolicy struct {
sync.Mutex
cachePolicyConfig
list *lfuList
removeFiles chan string
closeChan chan int
}
var _ cachePolicy = &lfuPolicy{}
func (l *lfuPolicy) StartPolicy() error {
log.Trace("lfuPolicy::StartPolicy")
go l.clearCache()
return nil
}
func (l *lfuPolicy) ShutdownPolicy() error {
log.Trace("lfuPolicy::ShutdownPolicy")
l.closeChan <- 1
return nil
}
func (l *lfuPolicy) UpdateConfig(config cachePolicyConfig) error {
log.Trace("lfuPolicy::UpdateConfig")
l.maxSizeMB = config.maxSizeMB
l.highThreshold = config.highThreshold
l.lowThreshold = config.lowThreshold
l.maxEviction = config.maxEviction
l.list.maxSizeMB = config.maxSizeMB
l.list.upperThresh = config.highThreshold
l.list.lowerThresh = config.lowThreshold
l.list.cacheTimeout = config.cacheTimeout
l.policyTrace = config.policyTrace
return nil
}
func (l *lfuPolicy) CacheValid(name string) {
log.Trace("lfuPolicy::CacheValid : %s", name)
l.list.Lock()
defer l.list.Unlock()
l.list.put(name)
}
func (l *lfuPolicy) CacheInvalidate(name string) {
log.Trace("lfuPolicy::CacheInvalidate : %s", name)
if l.cacheTimeout == 0 {
l.CachePurge(name)
}
}
func (l *lfuPolicy) CachePurge(name string) {
log.Trace("lfuPolicy::CachePurge : %s", name)
l.list.Lock()
defer l.list.Unlock()
l.list.delete(name)
l.removeFiles <- name
}
func (l *lfuPolicy) IsCached(name string) bool {
log.Trace("lfuPolicy::IsCached : %s", name)
l.list.Lock()
defer l.list.Unlock()
val := l.list.get(name)
if val != nil {
log.Debug("lfuPolicy::IsCached : %s found", name)
return true
} else {
log.Debug("lfuPolicy::IsCached : %s not found", name)
return false
}
}
func (l *lfuPolicy) Name() string {
return "lfu"
}
func (l *lfuPolicy) clearItemFromCache(path string) {
azPath := strings.TrimPrefix(path, l.tmpPath)
if azPath[0] == '/' {
azPath = azPath[1:]
}
flock := l.fileLocks.Get(azPath)
if l.fileLocks.Locked(azPath) {
log.Warn("lfuPolicy::DeleteItem : File in under download %s", azPath)
l.CacheValid(path)
return
}
flock.Lock()
defer flock.Unlock()
// Check if there are any open handles to this file or not
if flock.Count() > 0 {
log.Err("lfuPolicy::clearItemFromCache : File in use %s", path)
l.CacheValid(path)
return
}
// There are no open handles for this file so its safe to remove this
err := deleteFile(path)
if err != nil && !os.IsNotExist(err) {
log.Err("lfuPolicy::DeleteItem : failed to delete local file %s [%s]", path, err.Error())
}
// File was deleted so try clearing its parent directory
// TODO: Delete directories up the path recursively that are "safe to delete". Ensure there is no race between this code and code that creates directories (like OpenFile)
// This might require something like hierarchical locking.
}
func (l *lfuPolicy) clearCache() {
log.Trace("lfuPolicy::clearCache")
for {
select {
case path := <-l.removeFiles:
l.clearItemFromCache(path)
case <-l.closeChan:
return
}
}
}
func NewLFUPolicy(cfg cachePolicyConfig) cachePolicy {
pol := &lfuPolicy{
cachePolicyConfig: cfg,
removeFiles: make(chan string, 10),
closeChan: make(chan int, 10),
}
pol.list = newLFUList(cfg.maxSizeMB, cfg.lowThreshold, cfg.highThreshold, pol.removeFiles, cfg.tmpPath, cfg.cacheTimeout)
return pol
}
//Double DoublyLinkedList Implementation for O(1) lfu
type dataNode struct {
key string
frequency uint64
next *dataNode
prev *dataNode
timer *time.Timer
}
func newDataNode(key string) *dataNode {
return &dataNode{
key: key,
frequency: 1,
}
}
type dataNodeLinkedList struct {
size uint64
first *dataNode
last *dataNode
}
func (dl *dataNodeLinkedList) pop() *dataNode {
if dl.size == 0 {
return nil
}
return dl.remove(dl.first)
}
func (dl *dataNodeLinkedList) remove(node *dataNode) *dataNode {
if dl.size == 0 {
return nil
}
if dl.first == dl.last {
dl.first = nil
dl.last = nil
} else if dl.first == node {
temp := dl.first
dl.first = temp.next
temp.next = nil
dl.first.prev = nil
} else if dl.last == node {
temp := dl.last
dl.last = temp.prev
temp.prev = nil
dl.last.next = nil
} else {
nextNode := node.next
prevNode := node.prev
prevNode.next = nextNode
nextNode.prev = prevNode
node.next = nil
node.prev = nil
}
dl.size--
return node
}
func (dl *dataNodeLinkedList) push(node *dataNode) {
if dl.first == nil {
dl.first = node
dl.last = node
} else {
temp := dl.last
temp.next = node
node.prev = temp
dl.last = node
}
dl.size++
}
func newDataNodeLinkedList() *dataNodeLinkedList {
return &dataNodeLinkedList{}
}
type frequencyNode struct {
list *dataNodeLinkedList
next *frequencyNode
prev *frequencyNode
frequency uint64
}
func (fn *frequencyNode) pop() *dataNode {
return fn.list.pop()
}
func (fn *frequencyNode) remove(dn *dataNode) *dataNode {
return fn.list.remove(dn)
}
func (fn *frequencyNode) push(dn *dataNode) {
fn.list.push(dn)
}
func newFrequencyNode(freq uint64) *frequencyNode {
return &frequencyNode{
list: newDataNodeLinkedList(),
frequency: freq,
}
}
type lfuList struct {
sync.Mutex
first *frequencyNode
last *frequencyNode
dataNodeMap map[string]*dataNode
freqNodeMap map[uint64]*frequencyNode
size uint64
maxSizeMB float64
lowerThresh float64
upperThresh float64
deleteFiles chan string
cachePath string
cacheAge uint64
cacheTimeout uint32
}
func (list *lfuList) deleteFrequency(freq uint64) {
freqNode := list.freqNodeMap[freq]
if list.first == list.last {
list.first = nil
list.last = nil
} else if list.first == freqNode {
list.first = list.first.next
list.first.prev = nil
freqNode.next = nil
} else if list.last == freqNode {
list.last = list.last.prev
list.last.next = nil
freqNode.prev = nil
} else {
nextNode := freqNode.next
prevNode := freqNode.prev
nextNode.prev = prevNode
prevNode.next = nextNode
freqNode.next = nil
freqNode.prev = nil
}
list.size--
delete(list.freqNodeMap, freq)
}
func (list *lfuList) addFrequency(freq uint64, freqNode *frequencyNode, prevFreqNode *frequencyNode) {
if list.first == nil && list.last == nil {
list.first = freqNode
list.last = freqNode
list.freqNodeMap[freq] = freqNode
list.size++
return
}
if prevFreqNode == nil {
prevFreqNode = list.first
}
for prevFreqNode.next != nil && freq > prevFreqNode.next.frequency {
prevFreqNode = prevFreqNode.next
}
if prevFreqNode == nil {
freqNode.next = list.first
list.first.prev = freqNode
list.first = freqNode
} else if prevFreqNode == list.last {
prevFreqNode.next = freqNode
freqNode.prev = prevFreqNode
list.last = freqNode
} else {
nextNode := prevFreqNode.next
freqNode.next = nextNode
nextNode.prev = freqNode
prevFreqNode.next = freqNode
freqNode.prev = prevFreqNode
}
list.freqNodeMap[freq] = freqNode
list.size++
}
func (list *lfuList) promote(dataNode *dataNode) {
prevFreqNode := list.freqNodeMap[dataNode.frequency]
prevFreqNode.remove(dataNode)
dataNode.frequency += 1 + list.cacheAge
if newFreqNode, ok := list.freqNodeMap[dataNode.frequency]; ok {
newFreqNode.push(dataNode)
} else {
newFreqNode := newFrequencyNode(dataNode.frequency)
list.addFrequency(dataNode.frequency, newFreqNode, prevFreqNode)
list.freqNodeMap[dataNode.frequency] = newFreqNode
newFreqNode.push(dataNode)
}
if prevFreqNode.list.size == 0 {
list.deleteFrequency(prevFreqNode.frequency)
list.size--
}
}
func (list *lfuList) get(key string) *dataNode {
if node, ok := list.dataNodeMap[key]; ok {
if list.cacheTimeout > 0 {
node.timer.Stop()
}
list.promote(node)
list.setTimerIfValid(node)
return node
} else {
return nil
}
}
// Requires Lock()
func (list *lfuList) put(key string) {
if node, ok := list.dataNodeMap[key]; ok {
if list.cacheTimeout > 0 {
node.timer.Stop()
}
list.promote(node)
list.setTimerIfValid(node)
} else {
if usage := getUsagePercentage(list.cachePath, list.maxSizeMB); usage > list.upperThresh {
for usage > list.lowerThresh && list.first != nil {
toDeletePath := list.first.list.first.key
list.first.pop()
delete(list.dataNodeMap, toDeletePath)
if list.first.list.size == 0 {
list.deleteFrequency(list.first.frequency)
list.size--
usage = getUsagePercentage(list.cachePath, list.maxSizeMB)
}
list.deleteFiles <- toDeletePath
}
}
newNode := newDataNode(key)
list.dataNodeMap[key] = newNode
if freqNode, ok := list.freqNodeMap[newNode.frequency]; ok {
freqNode.push(newNode)
} else {
freqNode := newFrequencyNode(newNode.frequency)
list.freqNodeMap[newNode.frequency] = freqNode
freqNode.push(newNode)
list.addFrequency(newNode.frequency, freqNode, nil)
}
list.setTimerIfValid(newNode)
}
}
// Requires Lock()
func (list *lfuList) delete(key string) {
if node, ok := list.dataNodeMap[key]; ok {
if list.cacheTimeout > 0 {
node.timer.Stop()
}
freqNode := list.freqNodeMap[node.frequency]
freqNode.remove(node)
delete(list.dataNodeMap, key)
if freqNode.list.size == 0 {
list.deleteFrequency(node.frequency)
list.size--
}
list.deleteFiles <- node.key
list.cacheAge = node.frequency
}
}
func (list *lfuList) setTimerIfValid(node *dataNode) {
if list.cacheTimeout > 0 {
timer := time.AfterFunc(time.Duration(list.cacheTimeout)*time.Second, func() {
list.Lock()
list.delete(node.key)
list.Unlock()
})
node.timer = timer
}
}
func newLFUList(maxSizMB float64, lowerThresh float64, upperThresh float64, deleteChan chan string, cachePath string, cacheTimeout uint32) *lfuList {
return &lfuList{
dataNodeMap: make(map[string]*dataNode),
freqNodeMap: make(map[uint64]*frequencyNode),
size: 0,
maxSizeMB: maxSizMB,
lowerThresh: lowerThresh,
upperThresh: upperThresh,
deleteFiles: deleteChan,
cachePath: cachePath,
cacheTimeout: cacheTimeout,
}
}

Просмотреть файл

@ -1,286 +0,0 @@
/*
_____ _____ _____ ____ ______ _____ ------
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| --- | | | | |-----| |---- | | |-----| |----- ------
| | | | | | | | | | | | |
| ____| |_____ | ____| | ____| | |_____| _____| |_____ |_____
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
Copyright © 2020-2024 Microsoft Corporation. All rights reserved.
Author : <blobfusedev@microsoft.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
*/
package file_cache
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"testing"
"time"
"github.com/Azure/azure-storage-fuse/v2/common"
"github.com/Azure/azure-storage-fuse/v2/common/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type lfuPolicyTestSuite struct {
suite.Suite
assert *assert.Assertions
policy *lfuPolicy
}
var cache_path = filepath.Join(home_dir, "file_cache")
func (suite *lfuPolicyTestSuite) SetupTest() {
err := log.SetDefaultLogger("silent", common.LogConfig{Level: common.ELogLevel.LOG_DEBUG()})
if err != nil {
panic("Unable to set silent logger as default.")
}
suite.assert = assert.New(suite.T())
os.Mkdir(cache_path, fs.FileMode(0777))
config := cachePolicyConfig{
tmpPath: cache_path,
cacheTimeout: 0,
maxEviction: defaultMaxEviction,
maxSizeMB: 0,
highThreshold: defaultMaxThreshold,
lowThreshold: defaultMinThreshold,
fileLocks: &common.LockMap{},
}
suite.setupTestHelper(config)
}
func (suite *lfuPolicyTestSuite) setupTestHelper(config cachePolicyConfig) {
suite.policy = NewLFUPolicy(config).(*lfuPolicy)
suite.policy.StartPolicy()
}
func (suite *lfuPolicyTestSuite) cleanupTest() {
suite.policy.ShutdownPolicy()
os.RemoveAll(cache_path)
}
func (suite *lfuPolicyTestSuite) TestDefault() {
defer suite.cleanupTest()
suite.assert.EqualValues("lfu", suite.policy.Name())
suite.assert.EqualValues(0, suite.policy.cacheTimeout) // cacheTimeout does not change
suite.assert.EqualValues(defaultMaxEviction, suite.policy.maxEviction)
suite.assert.EqualValues(0, suite.policy.maxSizeMB)
suite.assert.EqualValues(defaultMaxThreshold, suite.policy.highThreshold)
suite.assert.EqualValues(defaultMinThreshold, suite.policy.lowThreshold)
}
func (suite *lfuPolicyTestSuite) TestUpdateConfig() {
defer suite.cleanupTest()
config := cachePolicyConfig{
tmpPath: cache_path,
cacheTimeout: 120,
maxEviction: 100,
maxSizeMB: 10,
highThreshold: 70,
lowThreshold: 20,
fileLocks: &common.LockMap{},
}
suite.policy.UpdateConfig(config)
suite.assert.NotEqualValues(120, suite.policy.cacheTimeout) // cacheTimeout does not change
suite.assert.EqualValues(0, suite.policy.cacheTimeout) // cacheTimeout does not change
suite.assert.EqualValues(100, suite.policy.maxEviction)
suite.assert.EqualValues(10, suite.policy.maxSizeMB)
suite.assert.EqualValues(70, suite.policy.highThreshold)
suite.assert.EqualValues(20, suite.policy.lowThreshold)
}
func (suite *lfuPolicyTestSuite) TestCacheValidNew() {
defer suite.cleanupTest()
suite.policy.CacheValid("temp")
node := suite.policy.list.get("temp")
suite.assert.NotNil(node)
suite.assert.EqualValues("temp", node.key)
suite.assert.EqualValues(2, node.frequency) // the get will promote the node
}
func (suite *lfuPolicyTestSuite) TestClearItemFromCache() {
defer suite.cleanupTest()
f, _ := os.Create(cache_path + "/test")
suite.policy.clearItemFromCache(f.Name())
_, attr := os.Stat(f.Name())
suite.assert.NotEqual(nil, attr.Error())
}
func (suite *lfuPolicyTestSuite) TestCacheValidExisting() {
defer suite.cleanupTest()
suite.policy.CacheValid("temp")
suite.policy.CacheValid("temp")
node := suite.policy.list.get("temp")
suite.assert.NotNil(node)
suite.assert.EqualValues("temp", node.key)
suite.assert.EqualValues(3, node.frequency) // the get will promote the node
}
func (suite *lfuPolicyTestSuite) TestCacheInvalidate() {
defer suite.cleanupTest()
suite.policy.CacheValid("temp")
suite.policy.CacheInvalidate("temp") // this is equivalent to purge since timeout=0
node := suite.policy.list.get("temp")
suite.assert.Nil(node)
}
func (suite *lfuPolicyTestSuite) TestCacheInvalidateTimeout() {
defer suite.cleanupTest()
suite.cleanupTest()
config := cachePolicyConfig{
tmpPath: cache_path,
cacheTimeout: 1,
maxEviction: defaultMaxEviction,
maxSizeMB: 0,
highThreshold: defaultMaxThreshold,
lowThreshold: defaultMinThreshold,
fileLocks: &common.LockMap{},
}
suite.setupTestHelper(config)
suite.policy.CacheValid("temp")
suite.policy.CacheInvalidate("temp")
node := suite.policy.list.get("temp")
suite.assert.NotNil(node)
suite.assert.EqualValues("temp", node.key)
suite.assert.EqualValues(2, node.frequency) // the get will promote the node
}
func (suite *lfuPolicyTestSuite) TestCachePurge() {
defer suite.cleanupTest()
suite.policy.CacheValid("temp")
suite.policy.CachePurge("temp")
node := suite.policy.list.get("temp")
suite.assert.Nil(node)
}
func (suite *lfuPolicyTestSuite) TestIsCached() {
defer suite.cleanupTest()
suite.policy.CacheValid("temp")
suite.assert.True(suite.policy.IsCached("temp"))
}
func (suite *lfuPolicyTestSuite) TestIsCachedFalse() {
defer suite.cleanupTest()
suite.assert.False(suite.policy.IsCached("temp"))
}
func (suite *lfuPolicyTestSuite) TestTimeout() {
defer suite.cleanupTest()
suite.cleanupTest()
config := cachePolicyConfig{
tmpPath: cache_path,
cacheTimeout: 1,
maxEviction: defaultMaxEviction,
maxSizeMB: 0,
highThreshold: defaultMaxThreshold,
lowThreshold: defaultMinThreshold,
fileLocks: &common.LockMap{},
}
suite.setupTestHelper(config)
suite.policy.CacheValid("temp")
time.Sleep(5 * time.Second) // Wait for time > cacheTimeout, the file should no longer be cached
suite.assert.False(suite.policy.IsCached("temp"))
}
func (suite *lfuPolicyTestSuite) TestMaxEvictionDefault() {
defer suite.cleanupTest()
suite.cleanupTest()
config := cachePolicyConfig{
tmpPath: cache_path,
cacheTimeout: 1,
maxEviction: defaultMaxEviction,
maxSizeMB: 0,
highThreshold: defaultMaxThreshold,
lowThreshold: defaultMinThreshold,
fileLocks: &common.LockMap{},
}
suite.setupTestHelper(config)
for i := 1; i < 5000; i++ {
suite.policy.CacheValid("temp" + fmt.Sprint(i))
}
time.Sleep(5 * time.Second) // Wait for time > cacheTimeout, the file should no longer be cached
for i := 1; i < 5000; i++ {
suite.assert.False(suite.policy.IsCached("temp" + fmt.Sprint(i)))
}
}
func (suite *lfuPolicyTestSuite) TestMaxEviction() {
defer suite.cleanupTest()
suite.cleanupTest()
config := cachePolicyConfig{
tmpPath: cache_path,
cacheTimeout: 1,
maxEviction: 5,
maxSizeMB: 0,
highThreshold: defaultMaxThreshold,
lowThreshold: defaultMinThreshold,
fileLocks: &common.LockMap{},
}
suite.setupTestHelper(config)
for i := 1; i < 5; i++ {
suite.policy.CacheValid("temp" + fmt.Sprint(i))
}
time.Sleep(5 * time.Second) // Wait for time > cacheTimeout, the file should no longer be cached
for i := 1; i < 5; i++ {
suite.assert.False(suite.policy.IsCached("temp" + fmt.Sprint(i)))
}
}
func TestLFUPolicyTestSuite(t *testing.T) {
suite.Run(t, new(lfuPolicyTestSuite))
}

Просмотреть файл

@ -37,6 +37,7 @@ import (
"fmt"
"io/fs"
"os"
"path/filepath"
"testing"
"time"
@ -52,6 +53,8 @@ type lruPolicyTestSuite struct {
policy *lruPolicy
}
var cache_path = filepath.Join(home_dir, "file_cache")
func (suite *lruPolicyTestSuite) SetupTest() {
// err := log.SetDefaultLogger("silent", common.LogConfig{Level: common.ELogLevel.LOG_DEBUG()})
// if err != nil {

14
go.mod
Просмотреть файл

@ -3,10 +3,10 @@ module github.com/Azure/azure-storage-fuse/v2
go 1.20
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.1.1
github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.1.3
github.com/JeffreyRichter/enum v0.0.0-20180725232043-2567042f9cda
github.com/fsnotify/fsnotify v1.7.0
github.com/golang/mock v1.6.0
@ -15,9 +15,9 @@ require (
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/radovskyb/watcher v1.0.7
github.com/sevlyar/go-daemon v0.1.6
github.com/spf13/cobra v1.8.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.18.2
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
github.com/vibhansa-msft/tlru v0.0.0-20240410102558-9e708419e21f
go.uber.org/atomic v1.11.0
@ -27,7 +27,7 @@ require (
)
require (
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@ -42,7 +42,7 @@ require (
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
@ -50,7 +50,7 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect

24
go.sum
Просмотреть файл

@ -1,14 +1,14 @@
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 h1:YUUxeiOWgdAQE3pXt2H7QXzZs0q8UBjgRbl56qo8GYM=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2/go.mod h1:dmXQgZuiSubAecswZE+Sm8jkvEa7kQgTPVRvwL/nd0E=
github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.1.1 h1:mkaGMgFkpDJVs7QUQrHvqEEpJFvoDrqGaHqMkywhGN0=
github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.1.1/go.mod h1:3S0vo7Y+O3Fjnnon5JXVrlG2IrfQkXasvKWB4OwX1lk=
github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.1.3 h1:RxiW5e1f3kgm6WGsnaRcnF1BOI+RnbwGKLSz+KPbxGY=
github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.1.3/go.mod h1:X6kh3l8pYjkOCz+PNLSrlyAhQSU/Cmkdnx72LwRwWZI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/JeffreyRichter/enum v0.0.0-20180725232043-2567042f9cda h1:NOo6+gM9NNPJ3W56nxOKb4164LEw094U0C8zYQM8mQU=
@ -63,8 +63,8 @@ github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs=
@ -77,8 +77,8 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -101,8 +101,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=

Просмотреть файл

@ -1,6 +1,6 @@
#!/bin/bash
work_dir=$(echo $1 | sed 's:/*$::')
version="1.22.1"
version="1.22.4"
arch=`hostnamectl | grep "Arch" | rev | cut -d " " -f 1 | rev`
if [ $arch != "arm64" ]
@ -13,3 +13,4 @@ wget "https://golang.org/dl/go$version.linux-$arch.tar.gz" -P "$work_dir"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "$work_dir"/go"$version".linux-$arch.tar.gz
sudo ln -sf /usr/local/go/bin/go /usr/bin/go
sudo ln -sf /usr/local/go/bin/gofmt /usr/bin/gofmt

Просмотреть файл

@ -281,7 +281,7 @@ func (suite *dirTestSuite) TestDirGetStats() {
// # Change mod of directory
func (suite *dirTestSuite) TestDirChmod() {
if suite.adlsTest == true {
dirName := suite.testPath + "/test3"
dirName := suite.testPath + "/testchmod"
err := os.Mkdir(dirName, 0777)
suite.Equal(nil, err)

36
testdata/config/azure_key_lfu.yaml поставляемый
Просмотреть файл

@ -1,36 +0,0 @@
logging:
level: log_debug
file-path: "blobfuse2-logs.txt"
type: base
components:
- libfuse
- file_cache
- attr_cache
- azstorage
libfuse:
attribute-expiration-sec: 0
entry-expiration-sec: 0
negative-entry-expiration-sec: 0
ignore-open-flags: true
file_cache:
path: { 1 }
policy: lfu
max-size-mb: 2048
allow-non-empty-temp: true
cleanup-on-start: true
attr_cache:
timeout-sec: 3600
azstorage:
type: { ACCOUNT_TYPE }
endpoint: { ACCOUNT_ENDPOINT }
use-http: false
account-name: { NIGHTLY_STO_ACC_NAME }
account-key: { NIGHTLY_STO_ACC_KEY }
mode: key
container: { 0 }
tier: hot